将NSTask的输出直接输出到文件?

时间:2012-06-15 21:23:04

标签: cocoa pipe nstask

直接管道和NSTask输出到文件的最佳方法是什么?我希望在内存中尽可能少地使用缓冲区。

2 个答案:

答案 0 :(得分:2)

在启动NSTask之前,将输出文件的标准输出和标准错误(setStandardOutput:setStandardError:)设置为NSFileHandle(如果您想要不同的话,请设置文件每个输出一个。)

NSFileHandle只是底层OS文件描述符的包装器,NSTask将执行相应的工作以将其连接到指定的输出(即它很可能会执行dup(2) )。不应引入中间内存缓冲区。

启动NSTask后,您可以(并且应该)关闭代码中的NSFileHandle

答案 1 :(得分:0)

我将回顾 CRD 的正确答案,添加一个演示代码片段。

这是一个启动 NSTask 以收集一些日志的片段(使用“log show”命令行工具,将标准输出重定向到一个文件,而无需为此分配和维护缓冲区。

NSString *logFilePath = [@"~/Desktop/MyLog.log" stringByStandardizingPath];
NSFileHandle *outFileHandle = [NSFileHandle fileHandleForWritingAtPath:logFilePath];
if(outFileHandle == nil) {
    [[NSFileManager defaultManager] createFileAtPath:logFilePath contents:nil attributes:nil];
    outFileHandle = [NSFileHandle fileHandleForWritingAtPath:logFilePath]; // create the file if needed
} else {
    [outFileHandle seekToEndOfFile]; // append to file if it already exists
}

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/log"];
[task setArguments: @[@"show", @"--predicate", @"process == \"myProcessName\""]];
[task setStandardOutput: outFileHandle];

@try {
    [task launch];
    [outFileHandle closeFile];  // task already holds it, we need not.
    [task waitUntilExit];
    int status = [task terminationStatus];
    switch (status) {
        case EXIT_SUCCESS: {
            if ([[NSFileManager defaultManager] fileExistsAtPath:logFilePath] == NO)  {
                NSLog(@"Log file not created for some reason, but task succeeded.");
            }
            break;
        }
        case EXIT_FAILURE:
        default:
            NSLog(@"Failed to extract logs. Error:%d", status);
            break;
    }
} @catch (NSException *exception) {
    NSLog(@"Exception occurred running task: %@", exception);
}