我使用NSTask运行shell命令并通过NSPipe输出数据。首先,我使用波纹管方法读取输出数据,这没有任何问题。
- (void)outputAvailable:(NSNotification *)aNotification {
NSString *newOutput;
NSMutableData *allData = [[NSMutableData alloc] init];
NSData *taskData = nil;
if((taskData = [readHandle availableData]) && [taskData length])
newOutput = [[NSString alloc] initWithData:allData encoding:NSASCIIStringEncoding];
NSLog(@"%@", newOutput);
[readHandle readInBackgroundAndNotify];
}
该方法的问题是它只输出4096字节的数据。所以我使用while
循环来获取更多数据,修改方法如下:
- (void)outputAvailable:(NSNotification *)aNotification {
NSString *newOutput;
NSMutableData *allData; //Added.
NSData *taskData = nil;
while ((taskData = [readHandle availableData]) && [taskData length]) {
[allData appendData:taskData];
}
newOutput = [[NSString alloc] initWithData:allData encoding:NSASCIIStringEncoding];
NSLog(@"%@", newOutput);
[readHandle readInBackgroundAndNotify];
}
然后出现问题:程序在while
循环中阻塞,无法执行以下语句。我确保allData
是我想要的,但在追加最后一个数据块之后,它就是阻塞的。
你能给我一些解决方案吗?感谢。
答案 0 :(得分:0)
你的while()
循环有效阻止了进一步的通知,导致整个程序阻塞等待刷新缓冲区的东西。
您应该readInBackgroundAndNotify
,然后在每个通知上取消availableBytes
,将其附加到您的NSMutableData
(可能存在于实例变量中)。处理通知时,请勿尝试等待更多数据或执行任何类型的while
循环。当有更多数据可用时,系统会通知您。
即。系统会将数据推送给您,您不会从系统中提取数据。
while()
循环正在这样做。咖啡不够。我的坏。
最后一个块很可能是因为你的外部进程没有关闭管道;没有收到EOF,因此,程序正在等待永远到达的更多数据。
或者:
确保后台任务退出
检测您何时收到足够数据并终止流程
如果您正在进行某种转换程序(例如,tr
),您在其中编写有关进程标准输入的数据,则可能需要关闭标准输入管道。