Cocoa 管道NSTask';直接输出到文件?
通过管道将NSTask的输出直接传输到文件的最佳方式是什么?我希望在内存中使用尽可能少的缓冲区。在启动Cocoa 管道NSTask';直接输出到文件?,cocoa,pipe,nstask,Cocoa,Pipe,Nstask,通过管道将NSTask的输出直接传输到文件的最佳方式是什么?我希望在内存中使用尽可能少的缓冲区。在启动NSTask之前,将输出文件的标准输出和标准错误(setstandardsoutput:,setStandardError:)设置为NSFileHandle) NSFileHandle只是底层OS文件描述符的包装,而NSTask将执行适当的工作,将其连接到指定的输出(即,它很可能执行dup(2))。不应引入中间内存缓冲区 启动NSTask后,您可以(并且应该)关闭代码中的NSFileHandle
NSTask
之前,将输出文件的标准输出和标准错误(setstandardsoutput:
,setStandardError:
)设置为NSFileHandle
)
NSFileHandle
只是底层OS文件描述符的包装,而NSTask
将执行适当的工作,将其连接到指定的输出(即,它很可能执行dup(2))。不应引入中间内存缓冲区
启动
NSTask
后,您可以(并且应该)关闭代码中的NSFileHandle
。我将重述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);
}
为什么需要关闭
NSFileHandle
?关闭它不意味着它不会向文件写入更多数据吗?这样命令生成的数据就不会被写入,对吗?@Alex-否。底层操作系统文件描述符是对打开的文件/管道/套接字的引用。其中一些DSCPTR具有固定用途;标准输入,输出&error;其他值在进程打开文件时分配(dscptr实际上是一个小整数,0表示标准输入,1表示标准输出,2表示标准错误)。设置标准输出:和朋友要做的是获取任意dscptr并将其复制到新任务进程的相应std dscptr上。进程启动后,关闭原始dscptr,使文件在std dscptr上保持打开状态。有关详细信息,请参阅C/Unix指南。要演示的代码很少?我几乎不知道如何使用C将此NSFileHandle创建为一个新的不存在的文件,并确保它将被创建?或者我应该首先创建该文件,打开它,并以某种方式使NSTask写入它的末尾?请advise@MottiShneor-按照SO的方式阅读NSFileHandle
文档等,然后设计并尝试一些代码。如果遇到问题,请提出新问题c概述你的设计,展示你的代码,并解释你在哪里让它工作。