Bac*_*ach 4 objective-c tail nstask
我需要实时将最后添加的行读取到日志文件中,并捕获添加的那一行。
类似于 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);
Run Code Online (Sandbox Code Playgroud)
使用时我可以看到预期的输出:
[server setLaunchPath:@"/bin/ls"];
Run Code Online (Sandbox Code Playgroud)
如何捕获该尾部 NSTask 的输出?
这种方法有什么替代方法,我可以打开一个流到文件,每次添加一行时,将它输出到屏幕上?(基本日志功能)
这样做有点棘手,因为在返回之前readDataToEndOfFile会等到tail关闭输出流,但tail -f永远不会关闭输出流(stdout)。然而,这对于基本的 CI/O 代码来说实际上非常简单,所以我创建了一个简单的FileTailer类,您可以查看。这不是什么花哨的东西,但它应该向您展示它是如何完成的。我这里还有的来源FileTailer.h,FileTailer.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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
你可以很简单地称呼它,像这样:
FileTailer *tail = [[[FileTailer alloc] initWithStream:stdin refreshPeriod:3.0] autorelease];
[tail readIndefinitely:^ void (int ch) { printf("%c", ch); }];
Run Code Online (Sandbox Code Playgroud)
(警告:我写这个FileTailer类的速度很快,所以它现在有点难看,应该清理一下,但它应该作为一个关于如何无限期读取文件的好例子,à la tail -f。)
| 归档时间: |
|
| 查看次数: |
1355 次 |
| 最近记录: |