I am generating relatively large files using Perl. The files I am generating are of two kinds:
-
Table files, i.e. textual files I print line by line (row by row), which contain mainly numbers. A typical line looks like:
126891 126991 14545 12 -
Serialized objects I create then store into a file using
Storable::nstore. These objects usually contain some large hash with numeric values. The values in the object might have beenpacked to save on space (and the objectunpacks each value before using it).
Currently I’m usually doing the following:
use IO::Compress::Gzip qw(gzip $GzipError);
# create normal, uncompressed file ($out_file)
# ...
# compress file using gzip
my $gz_out_file = "$out_file.gz";
gzip $out_file => $gz_out_file or die "gzip failed: $GzipError";
# delete uncompressed file
unlink($out_file) or die "can't unlink file $out_file: $!";
This is quite inefficient since I first write the large file to disk, then gzip read it again and compresses it. So my questions are as following:
-
Can I create a compressed file without first writing a file to disk? Is it possible to create a compressed file sequentially, i.e. printing line-by-line like in scenario (1) described earlier?
-
Does
Gzipsounds like an appropriate choice? aRe there any other recommended compressors for the kind of data I have described? -
Does it make sense to
packvalues in an object that will later be stored and compressed anyway?
My considerations are mainly saving on disk space and allowing fast decompression later on.
You can use
IO::ZliborPerlIO::gzipto tie a file handle to compress on the fly.As for what compressors are appropriate, just try several and see how they do on your data. Also keep an eye on how much CPU/memory they use for compression and decompression.
Again, test to see how much
packhelps with your data, and how much it affects your performance. In some cases, it may be helpful. In others, it may not. It really depends on your data.