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