如何使用Perl动态编写压缩文件?

时间:2010-09-28 06:00:50

标签: perl serialization gzip compression

我使用Perl生成相对较大的文件。我生成的文件有两种:

  1. 表格文件,即逐行打印(逐行打印)的文本文件,主要包含数字。典型的行看起来像:

    126891 126991 14545 12

  2. 我创建的序列化对象然后使用Storable::nstore存储到文件中。这些对象通常包含一些带有数值的大哈希。对象中的值可能已pack以保存在空间上(并且在使用之前对象unpack的每个值)。

  3. 目前我通常会做以下事情:

    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: $!";
    

    这是非常低效的,因为我首先将大文件写入磁盘,然后gzip再次读取并压缩它。所以我的问题如下:

    1. 我可以在没有先将文件写入磁盘的情况下创建压缩文件吗?是否可以按顺序创建一个压缩文件,即像前面描述的方案(1)一样逐行打印?

    2. Gzip听起来是合适的选择吗? aRe还有其他推荐的压缩机用于我所描述的数据类型吗?

    3. 对象中的pack值是否有意义,以后会被存储和压缩?

    4. 我的考虑主要是节省磁盘空间并允许以后快速解压缩。

3 个答案:

答案 0 :(得分:8)

  1. 您可以使用IO::ZlibPerlIO::gzip绑定文件句柄以便动态压缩。

  2. 至于适合的压缩器,只需尝试几种,看看它们对数据的作用。还要注意它们用于压缩和解压缩的CPU /内存量。

  3. 再次,测试一下pack对您的数据有多大帮助,以及它对您的效果有多大影响。在某些情况下,它可能会有所帮助。在其他情况下,它可能不会。这实际上取决于您的数据。

答案 1 :(得分:2)

您也可以打开()文件句柄到标量而不是真实文件,并将此文件句柄与IO :: Compress :: Gzip一起使用。没有真正尝试过,但它应该工作。我使用与Net :: FTP类似的东西来避免在磁盘上创建文件。

  

从v5.8.0开始,Perl默认使用PerlIO构建。除非你改变了这个(即,配置-Uuseperlio),你可以通过以下方式直接打开文件句柄到Perl标量:

     

open($fh, '>', \$variable) || ..

来自open()

答案 2 :(得分:0)

IO :: Compress :: Zlib有一个可用于此的OO接口。

use strict;  
use warnings;
use IO::Compress::Gzip;

my $z = IO::Compress::Gzip->new('out.gz');
$z->print($_, "\n") for 0 .. 10;