直接管道和NSTask输出到文件的最佳方法是什么?我希望在内存中尽可能少地使用缓冲区。
答案 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);
}