Thu, 17 Apr 2008

Using In-memory tarballs with Archive::Tar

Archive::Tar is a useful library for working with tar archives from Perl. Unfortunately, one thing it doesn't allow is using data from memory as the archive. From the TODO section:

Allow archives to be passed in as string

Currently, we only allow opened filehandles or filenames, but not strings. The internals would need some reworking to facilitate stringified archives.

Fortunately, it does allow you to use a filehandle. I've previously mentioned about how useful the IO::Handle subsystem in perl is. And we should be able to use it in this case. The module we'll want is IO::String, which is a IO::Handle over a perl scalar. We can use it:

my $tar = new Archive::Tar(new IO::String($data));

Unfortunately when we run this now we get:

Cannot read compressed format in tar-mode at Foo.pm line 41
No data could be read from file at Foo.pm line 41

It turns out that this is because Archive::Tar uses IO::Zlib internally if the file isn't uncompressed, but this doesn't provide the ability to uncompress from a filehandle. The answer is to uncompress the data before passing it to Archive::Tar and the easiest way to do this is to use the IO::Uncompress::Gunzip module, so we can rewrite our code to:

my $tar = new Archive::Tar(new IO::Uncompress::Gunzip(new IO::String($data)));

Now when you run the script, Archive::Tar has an uncompressed tar stream. Yet another situation where IO::Handles comes to the rescue.

[] | # Read Comments (1) |

Comments

A couple of comments.  First, is there a reason why you're saying "new Archive::Tar" instead of "Archive::Tar->new()"?  That syntxa can get you unstuck in a few places if you're not careful.  See perlobj/Indirect Object Syntax for details.

Secondly, there's no need to use a module for getting a filehandle for a string any more.  You can say something like this since Perl 5.8.

  my $str;
  open my $fh, '<', $str;

(I'm not sure if that should be followed with "or die()" — I don't think anything could go wrong there).
Posted by Dominic Mitchell at Thu Apr 17 20:25:36 2008

Name:


E-mail:


URL:


Comment:


Please enter "fudge" to prove you are a human