您可以从Perl中的.tar.bz2存档流式传输每个文件吗?

布拉姆·范罗伊

我们有很多压缩数据,它们实际上是目录及其子目录(包含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。不过,我没有压缩方面的经验,因此在给定多个数据块的情况下,也许有一种方法可以重建文件行。

TL; DR:可以从BZIP2压缩的TAR归档流式传输文件内容(逐行或类似)吗?

斯蒂芬·乌尔里希(Steffen Ullrich)

Compress :: Raw :: Bzip2,它允许您逐块(即在流中)解压缩bzip2输入块。但是由于.tar.bz2首先是一个tar文件,然后使用bzip2进行压缩,因此您需要先将所有数据解压缩到tar文件中的文件位置,然后才能访问所需的数据,即无法在不解压的情况下查找文件,直到该文件为止。如果您对此感到满意,则可以使用Archive :: Tar :: Stream即将bzip2解码器的输入输入到流Tar解析器中。我从来没有亲自使用过它,但看起来它是专门为这种用例而开发的。

如果您可以选择更改输入文件的格式,我建议您使用一种将压缩文件存储在存档中的格式(例如ZIP),而不是压缩完整的存档(即.tar.bz2)。这样,您可以轻松地查找到特定的压缩文件并仅解压缩该文件,而不解压缩直到该文件的所有文件。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章