4

ログ ファイルに最後に追加された行をリアルタイムで読み取り、追加された行をキャプチャする必要があります。

Tail -f に似たもの。

したがって、私の最初の試みは、NSTask を使用して Tail -f を使用することでした。

以下のコードを使用して出力が表示されません。

    NSTask *server = [[NSTask alloc] init];
    [server setLaunchPath:@"/usr/bin/tail"];
    [server setArguments:[NSArray arrayWithObjects:@"-f", @"/path/to/my/LogFile.txt",nil]];

    NSPipe *outputPipe = [NSPipe pipe];
    [server setStandardInput:[NSPipe pipe]];
    [server setStandardOutput:outputPipe];

    [server launch];
    [server waitUntilExit];
    [server release];

    NSData *outputData = [[outputPipe fileHandleForReading] readDataToEndOfFile];
    NSString *outputString = [[[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding] autorelease];
    NSLog (@"Output \n%@", outputString);

次を使用すると、出力が期待どおりに表示されます。

[server setLaunchPath:@"/bin/ls"];
  1. そのテール NSTask の出力をキャプチャするにはどうすればよいですか?

  2. ストリームをファイルに開き、行が追加されるたびに画面に出力できるこの方法に代わるものはありますか? (基本的なロギング機能)

4

2 に答える 2

5

が戻る前に出力ストリームを閉じるreadDataToEndOfFileまで待機しますが、出力ストリーム (stdout) を閉じることはありません。ただし、これは実際には基本的な CI/O コードで行うのは非常に簡単なので、確認できる簡単なクラスを作成しました。派手なものではありませんが、それがどのように行われたかを示す必要があります。、、およびテスト ドライバーのソースは次のとおりです。tailtail -fFileTailerFileTailer.hFileTailer.m

クラスの要点はとてもシンプルです。ブロックを渡すと、ストリームから文字を読み取り (可能であれば)、ブロックに渡します。EOF に達すると、( によって決定されるrefresh) 秒数待機してから、ストリームの読み取りを再試行します。

- (void)readIndefinitely:(void (^)(int ch))action
{
    long pos = 0L;
    int ch = 0;

    while (1) {
        fseek(in, pos, SEEK_SET);
        int ch = fgetc(in);
        pos = ftell(in);
        if (ch != EOF) {
            action(ch);
        } else {
            [NSThread sleepForTimeInterval:refresh];
        }
    }
}

次のように、非常に簡単に呼び出すことができます。

FileTailer *tail = [[[FileTailer alloc] initWithStream:stdin refreshPeriod:3.0] autorelease];
[tail readIndefinitely:^ void (int ch) { printf("%c", ch); }];

(注意:私はFileTailerクラスをかなり速く書いたので、今はちょっと醜いので、少し整理する必要がありますが、ファイルを無期限に読み取る方法の適切な例として役立つはずtail -fです。)

于 2011-01-12T23:08:29.580 に答える
1

以下は、Objective-C で NSTask を介して「tail -f logfile」を使用する方法です。

asynctask.m -- NSTask でデータを処理するための非同期 stdin、stdout、および stderr ストリームを実装する方法を示すサンプル コード

...

GUI を使用しないアプリケーション (つまり、Foundation ベースのコマンド ライン ツール) であるため、asynctask.m は NSRunLoop を手動で実行して、非同期の "waitForDataInBackgroundAndNotify" 通知を使用できるようにします。さらに、asynctask.m は pthread_create(3) および pthread_detach(3) を使用して、NSTask の stdin に 64 KB を超える書き込みを行います。

asynctask.m のソース コードは、http: //www.cocoadev.com/index.pl? NSPipe で入手できます。

于 2011-01-14T13:49:16.257 に答える