2016-08-12 77 views
0

perl的gunzip把缓冲和gunzip把文件中有不同的字节顺序

我使用Perl v5.22.1,Storable 2.53_01和IO::Uncompress::Gunzip 2.068。

我想使用Perl来在内存中gunzip一个Storable文件,而不使用中间文件。

我有一个变量$zip_file = '/some/storable.gz'指向这个压缩文件。

如果我直接gunzip到一个文件,这工作正常,并且%root正确设置为Storable散列。

gunzip($zip_file, '/home/myusername/Programming/unzipped'); 
my %root = %{retrieve('/home/myusername/Programming/unzipped')}; 

但是,如果我用gunzip到内存中是这样的:

my $file; 
gunzip($zip_file, \$file); 
my %root = %{thaw($file)}; 

我得到的错误

Storable binary image v56.115 more recent than I am (v2.10)` 

所以可存储的幻数已屠杀:它永不那么高。

但是,解压缩缓冲区中的字符串仍然正确;缓冲区以pst开头,这是正确的Storable标题。它似乎只是像正在被破坏的整数那样的多字节变量。

这是否与字节排序有关,例如在写入文件缓冲区时写入文件的方式是一种方式,而在另一种方式中写入文件缓冲区的方式是?如何在不破坏我的整数的情况下将gunzip缓冲到缓冲区?

回答

3

这与解压缩无关,但使用retrieve而不是thaw。他们都期望有不同的输入,即thaw期望freeze的输出,而retrieve期望store的输出。 这可以用一个简单的测试来验证:

$ perl -MStorable -e 'my $x = {}; store($x,q[file.store])' 
$ perl -MStorable=freeze -e 'my $x = {}; print freeze($x)' > file.freeze 

在我的机器这给24个字节,以供store和20字节freeze创建的文件。如果我从file.store中删除前4个字节,则该文件相当于file.freeze,即商店刚添加了4个字节的标题。因此,您可能会尝试解压缩内存中的文件,删除前4个字节,并在其余部分运行thaw

+0

优秀答案 – Borodin

+0

这是对的!不幸的是,我没有创建可存储的文件,所以我无法选择使用冻结而不是存储。然而,我发现通过将$ file转换为文件句柄,可以检索'store'存储在内存中:'open my $ fake_fh,“<”,\ $ file;'然后使用'fd_retrieve($ fake_fh);' – Miguel