Pickwick has asked for the wisdom of the Perl Monks concerning the following question:
Dear monks,
in one of my applications I have a scalar with some zip data created using Archive::Zip in memory and I need to unzip it in another part of the application. Therefore I use IO::String with my already present scalar and gave that to Archive::Zip::Read. Everything seemed to work fine, the zip data got parsed without errors, I could fetch the members, their sizes etc., but whenever I wanted to access the contents of the members I got the following error:
IO error: seeking to local header
After some debugging in IO::String I found that seek fails because there's no more data attached, the following line evaluates to true and results 0 which leads to the error 4 returned from Archive::Zip.
my $buf = *$self->{buf} || return 0;As data can't strangely loose itself I did some more debugging and seemed to find the root cause: read in Archive::Zip::Archive is closing the file handle it gets if it finished successfully, resulting in IO::String::close deleting the associated buffer. When I call another IO::String::open on my instance after read with the same zipped data as before, I'm successfully able to extract the contents of my buffers.
Does this look like a bug in Archive::Zip or am I doing something wrong? One reason to close the handle I can think of may be that read can't know if one is really interested in data and not only in some pieces of information about the members and reopening the handle in case of a file is easy. But there's nothing documented anywhere about this behavior and one needs to know about those things for cases like mine, where I want to use IO::String. Is there anything more compatible which I could use with zipped data already in memory?
From my point of view the proper behavior of read would be to only close the file handle if it created it on it's own, but not if it got one from the caller.
One thing I could imagine as workaorund is to subclass IO::String as something like IO::(Archive)ZipString and reimplement close to do nothing, but DESTROY to call close on the super class. This way read couldn't close the handle, but no memory leak would occur.
Thanks for your suggestions.
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Using Archive::Zip reading from IO::String results in a seek error
by Anonymous Monk on Aug 18, 2013 at 03:14 UTC | |
by Pickwick (Beadle) on Aug 18, 2013 at 08:38 UTC | |
Re: Using Archive::Zip reading from IO::String results in a seek error
by Pickwick (Beadle) on Aug 19, 2013 at 07:50 UTC |