从NSTask管道中读取数据,因为它可用

时间:2014-10-02 20:16:28

标签: objective-c cocoa pipe stdout nstask

到目前为止,我有这个代码,目标是对我的NSTask的某些输出采取行动。本质上它(我的NSTask)是一个程序,随着时间的推移将字符串输出到控制台。我希望能够在控制台上显示某个字符串时,在我的cocoa Objective-C应用程序中调用一个方法。我的想法是将控制台输出传递给我的应用程序,该应用程序检查传递的字符串是否需要执行操作。

    NSPipe *pipe = [NSPipe pipe];
    NSFileHandle *file = pipe.fileHandleForReading;

    self.task = [[NSTask alloc] init];

    [self.task setStandardOutput: pipe];
    [self.task setStandardError: [self.task standardOutput]];

    self.task.launchPath = @"/usr/local/bin/taskThing";
    self.task.arguments = @[@"taskArg"];

    [self.task launch];


    NSMutableData *data = [NSMutableData dataWithCapacity:512];
    while ([self.task isRunning]) {
        [data appendData:[file availableData]];
    }
    [file closeFile];

    NSString *taskOut = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"task returned: %@ END", taskOut);

这基本上“崩溃”了应用程序,因为while循环导致它只是继续阅读,直到我杀死NSTasks进程。当我确定终止进程时,将记录任务记录的所有记录输出。所以它有点工作,我希望能够做的是在它们出现时对任务输出进行操作,任务将继续运行,所以我无法等待它在接收管道数据之前停止。有什么想法吗?

PS。我刚刚看到提到waitForDataInBackgroundAndNotify,希望这有帮助,也可以看一下。

1 个答案:

答案 0 :(得分:0)

我更多地关注waitForDataInBackgroundAndNotify。 在启动任务后的上述代码中,我删除了所有后续行,并替换为通知Observer

NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;

self.task = [[NSTask alloc] init];

[self.task setStandardOutput: pipe];
[self.task setStandardError: [self.task standardOutput]];

self.task.launchPath = @"/usr/local/bin/taskThing";
self.task.arguments = @[@"taskArg"];

[self.task launch];


[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(outData:) 
name:NSFileHandleDataAvailableNotification object:initialOutputFile];

[file waitForDataInBackgroundAndNotify];

在一种新方法中; " outData:"

- (void)outData:(NSNotification *)notification {
NSFileHandle *outputFile = (NSFileHandle *) [notification object];
NSData *data = [outputFile availableData];

if([data length]) {
    NSString *temp = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Here: %@", temp);
}

[outputFile waitForDataInBackgroundAndNotify];

}

这完全基于此question