Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa 管道NSTask';直接输出到文件?_Cocoa_Pipe_Nstask - Fatal编程技术网

Cocoa 管道NSTask';直接输出到文件?

Cocoa 管道NSTask';直接输出到文件?,cocoa,pipe,nstask,Cocoa,Pipe,Nstask,通过管道将NSTask的输出直接传输到文件的最佳方式是什么?我希望在内存中使用尽可能少的缓冲区。在启动NSTask之前,将输出文件的标准输出和标准错误(setstandardsoutput:,setStandardError:)设置为NSFileHandle) NSFileHandle只是底层OS文件描述符的包装,而NSTask将执行适当的工作,将其连接到指定的输出(即,它很可能执行dup(2))。不应引入中间内存缓冲区 启动NSTask后,您可以(并且应该)关闭代码中的NSFileHandle

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

在启动
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概述你的设计,展示你的代码,并解释你在哪里让它工作。