我们有很多压缩数据,它们实际上是包含 XML 文件的目录及其子目录的压缩磁带存档;例如
omega/
- alpha/
- a/
- file1.xml
- file2.xml
- file3.xml
- b/
- file1.xml
- file2.xml
- file3.xml
- c/
- ...
- beta/
- a/
- file1.xml
- file2.xml
- file3.xml
- b/
- ...
- c/
- ...
- gamma/
- a/
- ...
- b/
- ...
- c/
- ...
结果将是诸如 omega.tar.bz2
之类的文件,这些文件的大小可达数百 GB。
尽管我们知道这是一种存档文件类型,但如果我们仍然能够在需要时使用其内容,那就太好了。因此,我想知道是否可以以流的方式在 Perl 中读取这些文件,即无需首先解压和解压缩磁盘上的所有内容,也无需加载整个 *。 tar.bz2
文件写入内存。
我知道IO::Uncompress
你可以使用 Bunzip2,但据我所见和测试,这会将整个文件读入内存,这对于我们的大文件来说是不可能的。下面关于 Bunzipping 的示例代码(不包括 TAR)。
use strict;
use warnings;
use IO::Uncompress::Bunzip2 qw(bunzip2 $Bunzip2Error) ;
my $filename = '/path/to/file/file1.xml.bz2';
open(my $fh, '<', $filename)
or die "Could not open file '$filename' $!";
my $buffer ;
bunzip2 $filename => \$buffer
or die "bunzip2 failed: $Bunzip2Error\n";
print STDOUT "$buffer\n";
考虑到 TAR,还有 Archive::Extract
模块,允许将 .tar.bz2
文件(类型 tbz
)读取到 Extract Object
中,但这又会将整个文件读入这是我们巨大的文件不可能实现的内存。
由于我自己对该主题的研究,我认为不太可能以流式传输方式(即逐行)读取 BZIP2 的 TAR。不过,我没有压缩经验,所以也许有一种方法可以在给定多个数据 block 的情况下重建文件行。
Tl;dr:您可以从 BZIP2 压缩的 TAR 存档中流式传输文件内容(逐行或类似内容)吗?
最佳答案
有Compress::Raw::Bzip2它允许您逐 block 解压缩 bzip2 输入 block ,即在流中。但是,由于 .tar.bz2 首先是一个 tar 文件,然后使用 bzip2 进行压缩,因此您需要首先将所有数据解压缩到 tar 文件中的文件位置,然后才能访问所需的数据,即没有办法查找该文件而不解压该文件之前的所有内容。如果您对此感到满意,您也许可以使用 Archive::Tar::Stream ,即将 bzip2 解码器的输入输入到流式 Tar 解析器中。我自己从未使用过它,但看起来它就是专门为这种用例开发的。
如果您可以选择更改输入文件的格式,我建议您使用将压缩文件存储在存档中的格式(如 ZIP 那样),而不是压缩完整存档(即 .tar.bz2)。这样您就可以轻松地查找特定的压缩文件并仅解压缩该文件,而不是解压缩该文件之前的所有内容。
关于perl - 您可以从 Perl 中的 .tar.bz2 存档中逐文件、逐行流式传输吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40397489/