我正在尝试使用/ usr / bin / compress压缩文件,在没有文件名的情况下启动,以便从stdin获取数据并将压缩数据写入stdout。我用standardInput,Output& amp;管道创建任务。错误。在循环中,我从文件中读取一个数据块,写入任务的stdin,然后使用[NSFileHandle availableData]从stdout读取。我尝试过块大小为2K,8K和12K。在所有情况下,我的程序都会挂起。我的目标是10.6
我的代码结构的方式,我更喜欢它阻止在availableData上,因为在数据到达之前我不能做任何事情,并且调用者只在处理完成时才会返回。到目前为止,这都是主线程。一旦它工作,我将把这个部分移动到一个单独的线程,以便不阻塞main,是的,然后我需要让调用者在下级线程退出时接受异步完成。
init
{
self = [super init];
if (self) {
task = [[NSTask alloc] init];
NSPipe* stdin_Pipe = [NSPipe pipe];
NSPipe* stdoutPipe = [NSPipe pipe];
NSPipe* stderrPipe = [NSPipe pipe];
[task setStandardInput: stdin_Pipe];
[task setStandardOutput: stdoutPipe];
[task setStandardError: stderrPipe];
[task setLaunchPath: kCompressor];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver: self
selector: @selector (taskTerminated:)
name: NSTaskDidTerminateNotification
object: task];
[task launch];
}
return self;
}
写一些,读一些。什么都没说压缩决定写什么。
(NSData*) compressData: (NSData*) source
{
[[[task standardInput] fileHandleForWriting] writeData: source];
return [[[task standardOutput] fileHandleForReading] availableData];
}
...以及使用上一个代码段的代码:
(BOOL) compressFile: (NSString*) file
{
//...
NSData* fileDataBlock = [sourceFileHandle readDataOfLength: kTargetFileReadBlockLen];
while ( [fileDataBlock length] > 0) {
NSData* compressedData = [origFileCompress compressData: currentBuffer];
//...
}
}
gdb显示我的程序执行此操作(最新帧):
读取$ UNIX2003中的0x9a0ade5e
_NSReadFromFileDescriptor 中的0x91ebcc13
0x91ec3c64 in - [NSConcreteFileHandle availableData]
0x00002e8b in - [压缩compressData:]在CompressIt.m:266
活动监视器 - >示例流程显示/ usr / bin / compress执行此操作(最早的帧):
2672 fread(在libSystem.B.dylib中)+ 436 [0x7fff8a0e501a]
2672 __srefill1(在libSystem.B.dylib中)+ 27 [0x7fff8a0e50a5]
2672 _sread(在libSystem.B.dylib中)+ 19 [0x7fff8a0dce34]
2672 __sread(在libSystem.B.dylib中)+ 16 [0x7fff8a0e50ef]
2672读取$ NOCANCEL(在libSystem.B.dylib中)+ 10 [0x7fff8a095982]
答案 0 :(得分:0)
你无法控制compress
的工作方式 - 缓冲,输入与输出的关系等等 - 所以写一个块然后再读一个就不太可能了。
你显然知道线程(你打算稍后将代码移出主线程),所以只需将数据写入另一个线程中的管道 - 你可以使用GCD调度并发块,激活{{1一旦你这样做,你就把你的写作分解为&从管道中读取,他们每个人都可以按照自己的节奏前进。