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.


In reply to Using Archive::Zip reading from IO::String results in a seek error by Pickwick

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.