Re: NSTask with unzip
Re: NSTask with unzip
- Subject: Re: NSTask with unzip
- From: Ben Haller <email@hidden>
- Date: Sat, 27 Nov 2010 12:12:39 -0500
Here's a post that I found useful:
http://dev.notoptimal.net/2007/04/nstasks-nspipes-and-deadlocks-when.html
Dave, not sure what you mean here. NSPipe uses NSFileHandle. Does using an NSFileHandle directly change things somehow? If so, why? I think this is an avenue I haven't explored; once I (finally) figured out the right magic incantations to get things to work reliably with NSPipe, I now recycle that code everywhere I need an NSTask :->.
Ben Haller
McGill University
On 2010-11-27, at 11:48 AM, Dave DeLong wrote:
> The way I get around this is to use an NSFileHandle for standard out instead of an NSPipe. It's a bit less efficient, but slightly more convenient.
>
> Dave
>
> Sent from my iPhone
>
> On Nov 27, 2010, at 7:59 AM, Ben Haller <email@hidden> wrote:
>
>> On 2010-11-26, at 7:33 AM, gMail.com wrote:
>>
>>> Hi, I can properly unzip a zip file launching a NSTask with /usr/bin/unzip
>>> The task saves the unzipped file to the disk, then a I read the unzipped
>>> file in a NSData. Well. My question is:
>>> Can I do the same job without saving the unzipped file to the disk?
>>>
>>> I have tried to set the standard output to a pipe - which works well with
>>> other tasks - but here it doesn't work. The task never exits. Here's the
>>> wrong code:
>>>
>>> NSTask *unzip = [[[NSTask alloc] init] autorelease];
>>> [unzip setLaunchPath:@"/usr/bin/unzip"];
>>> [unzip setArguments:[NSArray arrayWithObjects:@"-p", zipfile,
>>> @"filetounzip", nil]];
>>>
>>> NSPipe *aPipe = [NSPipe pipe];
>>> [unzip setStandardOutput:aPipe];
>>> [unzip launch];
>>> [unzip waitUntilExit];
>>>
>>> if([unzip terminationStatus] == noErr){
>>> dictData = [NSMutableData data];
>>> while((dataOut = [aPipe availableData]) && [dataOut length]){
>>> [dictData appendData:dataOut];
>>> }
>>> }
>>
>> If I recall correctly, the problem is likely to be your use of -waitUntilExit. That API should apparently have a large red label on it ("Warnin', lark's vomit!") since everybody wants to use it this way. The problem is that the task's output pipe fills up because it isn't being serviced, and then things get locked up. You need to go with asynchronous reads to service the pipe as output gets stuffed into it. There should be lots of examples of this on this list, now that you know what to look for.
>>
>> What would be great would be a new call, along the lines of -dataFromWaitingUntilExit or some such, that does all this for you, since this is so commonly what people want to do.
>>
>> Ben Haller
>> McGill University
>>
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden