我使用Perl生成相对较大的文件。我生成的文件有两种:
表格文件,即逐行打印(逐行打印)的文本文件,主要包含数字。典型的行看起来像:
126891 126991 14545 12
我创建的序列化对象然后使用Storable::nstore
存储到文件中。这些对象通常包含一些带有数值的大哈希。对象中的值可能已pack
以保存在空间上(并且在使用之前对象unpack
的每个值)。
目前我通常会做以下事情:
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)一样逐行打印?
Gzip
听起来是合适的选择吗? aRe还有其他推荐的压缩机用于我所描述的数据类型吗?
对象中的pack
值是否有意义,以后会被存储和压缩?
我的考虑主要是节省磁盘空间并允许以后快速解压缩。
答案 0 :(得分:8)
您可以使用IO::Zlib
或PerlIO::gzip
绑定文件句柄以便动态压缩。
至于适合的压缩器,只需尝试几种,看看它们对数据的作用。还要注意它们用于压缩和解压缩的CPU /内存量。
再次,测试一下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;