2

Cbjective-C で小さな rsync プログラムを作成しようとしています。現在、NSTask を介して端末コマンド ラインにアクセスし、コマンド ラインの出力を NSTextField に表示される文字列に読み取ります。ただし、この小さなプログラムを非常に大きなファイル (約 8 GB) で使用すると、RSYNC が完了するまで出力が表示されません。プロセスの実行中に NSTextField を継続的に更新したい。私は次のコードを持っていて、アイデアを探しています!:

 -(IBAction)sync:(id)sender
{
    NSString *sourcePath = self.source.stringValue;
    NSString *destinationPath = self.destination.stringValue;

    NSLog(@"The source is %@. The destination is %@.", sourcePath, destinationPath);

    NSTask *task;
    task = [[NSTask alloc] init];
    [task setLaunchPath:@"/usr/bin/rsync"];

    NSArray *arguments;
    arguments = [NSArray arrayWithObjects: @"-rptWav", @"--progress", sourcePath, destinationPath, nil];
    [task setArguments: arguments];

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput: pipe];

       // [task setStandardInput:[NSPipe pipe]];

    NSFileHandle *file;
    file = [pipe fileHandleForReading];

    [task launch];

    NSData *data;
    data = [file readDataToEndOfFile];

    while ([task isRunning])
    {
        NSString *readString;
        readString = [[NSString alloc] initWithData: data encoding:NSUTF8StringEncoding];

        textView.string = readString;
        NSLog(@"grep returned:\n%@", readString);

    }

    }
4

1 に答える 1

0

OK、問題はパイプからデータを読み取る方法にあります。あなたが使用している:

NSData *data = [file readDataToEndOfFile];

パイプが閉じられるまで(子プロセスが終了したとき)、子プロセスによって書き込まれたすべてを一度に読み取ります。

あなたがする必要があるのは、一度に1文字ずつ読み取り、出力行を再構築することです。また、読み取るデータがないときにメイン UI スレッドが中断されないように、ノンブロッキング モードを使用する必要があります (メイン UI スレッドが完全に中断されないように、これはバックグラウンド スレッドで実行する必要があります)。

于 2012-10-16T06:58:30.700 に答える