3

将 NSTask 的输出直接通过管道传输到文件的最佳方法是什么?我想通过尽可能少的内存缓冲区。

4

2 回答 2

3

在启动之前,NSTask将标准输出和标准错误 ( setStandardOutput:, setStandardError:) 设置NSFileHandle为输出文件(或文件,如果您希望每个输出使用不同的文件)。

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

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

于 2012-06-16T01:53:30.763 回答
0

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

这是一个启动NSTask收集一些日志的片段(使用“日志显示”命令行工具,将标准输出重定向到文件而不分配和维护缓冲区来执行此操作。

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);
}
于 2021-02-16T13:47:13.680 回答