objective-c – 从Unix命令读取NSTask / NSPipe
发布时间:2020-12-16 03:33:25 所属栏目:百科 来源:网络整理
导读:我正在编写一个 Cocoa应用程序,它需要执行一个UNIX程序并逐行读取它的输出.我设置了NSTask和NSPipe: task = [[NSTask alloc] init];pipe = [NSPipe pipe];[task setStandardOutput:pipe];//... later ...[task setArguments:...];[task setLaunchPath:@"...
我正在编写一个
Cocoa应用程序,它需要执行一个UNIX程序并逐行读取它的输出.我设置了NSTask和NSPipe:
task = [[NSTask alloc] init]; pipe = [NSPipe pipe]; [task setStandardOutput:pipe]; //... later ... [task setArguments:...]; [task setLaunchPath:@"..."]; [task launch]; handle = [[task fileHandleForReading] retain]; 在程序通过[task terminate]指示它执行此操作之前,该命令不会终止.我已经尝试了几种从句柄中读取的方法,例如-readInBackgroundAndNotify,而([(data = [handle availableData])length]> 0)和-waitForDataInBackgroundAndNotify,但管道似乎永远不会产生任何数据.有什么方法可以“戳”NSTask或NSPipe来刷新数据吗? 编辑:使用-readInBackgroundAndNotify: [handle readInBackgroundAndNotify]; notification_block_t handlerBlock = ^(NSNotification *notification) { NSData *data = [[notification userInfo] objectForKey: NSFileHandleNotificationDataItem]; /*... do stuff ...*/ [self addNotification: handle block: handlerBlock]; }; [self addNotification: handler block: handlerBlock]; //... - (void)addNotification:(id)handle block:(notification_block_t)block { [[NSNotificationCenter defaultCenter] addObserverForName: NSFileHandleReadCompletionNotification object: handle queue: [NSOperationQueue mainQueue] usingBlock: block]; } 使用-waitForDataInBackgroundAndNotify: [handle waitForDataInBackgroundAndNotify]; notification_block_t handlerBlock = ^(NSNotification *notification) { NSData *data = [handle availableData]; /*... do stuff ...*/ }; [self addNotification: handler block: handlerBlock]; with while循环: [self startProcessingThread: handle]; //... - (void)startProcessingThread:(NSFileHandle *)handle { [[NSOperationQueue mainQueue] addOperation: [[[NSInvocationOperation alloc] initWithTarget: self selector: @selector(dataLoop:) object: handle] autorelease]]; } - (void)dataLoop:(NSFileHandle *)handle { NSData *data; while([(data = [handle availableData]) length] > 0) { /*... do stuff ...*/ } } 编辑2:参数设置如下(命令是tshark): NSArray *cmd = [NSArray arrayWithObjects:@"-R",@"http.request",@"-Tfields",@"-Eseparator='|'",@"-ehttp.host",@"-ehttp.request.method",@"-ehttp.request.uri",nil]; cmd = [[cmd arrayByAddingObjectsFromArray:[self.ports map:^(id arg1,NSUInteger idx) { return [NSString stringWithFormat:@"-d tcp.port==%d,http",[arg1 intValue]]; }]] arrayByAddingObject:[@"dst " stringByAppendingString: [self.hosts componentsJoinedByString:@" or dst "]]]; [self.tsharktask setArguments:cmd]; 解决方法
这是我通常如何做的一个工作示例:
task = [[NSTask alloc] init]; [task setLaunchPath:...]; NSArray *arguments; arguments = ...; [task setArguments:arguments]; NSPipe *outPipe; outPipe = [NSPipe pipe]; [task setStandardOutput:outPipe]; outFile = [outPipe fileHandleForReading]; [outFile waitForDataInBackgroundAndNotify]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(commandNotification:) name:NSFileHandleDataAvailableNotification object:nil]; [task launch]; - (void)commandNotification:(NSNotification *)notification { NSData *data = nil; while ((data = [self.outFile availableData]) && [data length]){ ... } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |