There are several free zlib frameworks for Cocoa available, have a look at 
http://www.timschroeder.net/2010/07/25/the-seven-cities-of-zip/ for a 
comparison.

--

Tim Schröder


Am 28.11.2010 um 23:51 schrieb Leonardo:

> Great! Thanks for the advises.
> Now I have to zip and unzip a NSData (not a zip file) to a NSData.
> In other words, I have to zip and unzip "data to data", without using any
> file. Some idea?
> 
> -- Leonardo
> 
> 
> 
>> Da: Ben Haller <bhcocoa...@sticksoftware.com>
>> Data: Sun, 28 Nov 2010 08:52:33 -0500
>> A: Leonardo <mac.iphone....@gmail.com>, Cocoa List 
>> <cocoa-dev@lists.apple.com>
>> Oggetto: Re: NSTask with unzip
>> 
>>  Yes, this looks good.  I like your category on NSFileHandle (not a
>> subclass!); it's cleaner than the code at the link I sent you, since it
>> doesn't just eat the error, and it's better as a category.
>> 
>>  Four things I would mention:
>> 
>> 1) Checking that the pipe could be created and actually has a file handle for
>> reading would be a good idea; [NSPipe pipe] is documented as being allowed to
>> return nil
>> 
>> 2) Checking -terminationStatus is a good idea once the task completes (after
>> you're done pulling data out, you can then safely call -waitUntilExit on the
>> task to be certain it has completed before calling -terminationStatus, AFAIK)
>> 
>> 3) You only use a pipe for standard out, not for standard in, but it's worth
>> noting that a pipe for standard in needs to receive a -closeFile call or the
>> file descriptor for that pipe doesn't get deleted correctly.  As a reminder 
>> to
>> myself about this issue, I just send -closeFile to all of the pipes I'm using
>> with a task, so that I don't forget to do it.  But your code is correct; I
>> mention this just in case someone reading the archives adapts this code to a
>> task that requires a standard in pipe.
>> 
>> 4) -launch can raise, so it is good to think about that; but as long as 
>> you're
>> comfortable with your method raising, your code seems fine to me.
>> 
>>  Good stuff!  If anybody on the list knows whether the bug that the
>> -availableDataOrError: hack circumvents has been fixed, and in what OS X
>> release, I'd love to know that so I know whether it's safe to delete that
>> rather unpleasant hack from my code.
>> 
>> Ben Haller
>> McGill University
>> 
>> 
>> On 2010-11-27, at 3:43 PM, Leonardo wrote:
>> 
>>> Ben, thank you so much! I have successfully done it.
>>> I post the code here for anyone to use it. I love this list.
>>> 
>>> - (NSData*)UnzipFile:(NSString*)sourcePath
>>> extractFileName:(NSString*)extractFileName
>>> {    
>>>   NSTask    *unzip = [[[NSTask alloc] init] autorelease];
>>>   NSPipe    *aPipe = [NSPipe pipe];
>>>   [unzip setStandardOutput:aPipe];
>>>   [unzip setLaunchPath:@"/usr/bin/unzip"];
>>>   [unzip setArguments:[NSArray arrayWithObjects:@"-p", sourcePath,
>>> extractFileName, nil]];
>>>   [unzip launch];
>>> 
>>>   NSMutableData    *dataOut = [NSMutableData data];
>>>   NSData            *dataIn = nil;
>>>   NSException        *error = nil;
>>> 
>>>   while((dataIn = [[aPipe fileHandleForReading]
>>> availableDataOrError:&error]) && [dataIn length] && error == nil){
>>>       [dataOut appendData:dataIn];
>>>   }
>>> 
>>>   if([dataOut length] && error == nil){
>>>       return dataOut;
>>>   }
>>> 
>>>   return nil;
>>> }
>>> 
>>> 
>>> // Then I subclassed NSFileHandler this way
>>> 
>>> @implementation NSFileHandle (MyOwnAdditions)
>>> - (NSData*)availableDataOrError:(NSException**)returnError
>>> {
>>>   for(;;){
>>>       @try{
>>>           return [self availableData];
>>>       }...@catch (NSException *e) {
>>>           if ([[e name] isEqualToString:NSFileHandleOperationException]) {
>>>               if ([[e reason] isEqualToString:@"*** -[NSConcreteFileHandle
>>> availableData]: Interrupted system call"]) {
>>>                   continue;
>>>               }
>>>               if (returnError)
>>>                   *returnError = e;
>>>               return nil;
>>>           }
>>>           @throw;
>>>       }
>>>   }
>>> }
>>> @end
>>> 
>>> 
>>>> Da: Ben Haller <bhcocoa...@sticksoftware.com>
>>>> Data: Sat, 27 Nov 2010 12:12:39 -0500
>>>> A: Dave DeLong <davedel...@me.com>
>>>> Cc: "gMail.com" <mac.iphone....@gmail.com>, Cocoa List
>>>> <cocoa-dev@lists.apple.com>
>>>> Oggetto: Re: NSTask with unzip
>>>> 
>>>> 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 <bhcocoa...@sticksoftware.com>
>>>>> 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 (Cocoa-dev@lists.apple.com)
>>>>>> 
>>>>>> 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:
>>>>>> http://lists.apple.com/mailman/options/cocoa-dev/davedelong%40me.com
>>>>>> 
>>>>>> This email sent to davedel...@me.com
>>>> 
>>> 
>>> 
>> 
> 
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> 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:
> http://lists.apple.com/mailman/options/cocoa-dev/tim%40timschroeder.net
> 
> This email sent to t...@timschroeder.net

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to