perl - 您可以从 Perl 中的 .tar.bz2 存档中逐文件、逐行流式传输吗?

标签 perl tar compression bzip2

我们有很多压缩数据,它们实际上是包含 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/

相关文章:

linux - 将文件从 tar 管道传输到命令

perl - 如何避免 perl 命令行参数错误并使用严格

perl - 如何使用 Perl 从大文件中删除非唯一行?

linux - backuppc 方法 tar 没有为共享转储的文件

asp.net-mvc - gzip 压缩不起作用并且无法在 chrome 中获取 304

perl - 我应该如何使用 Perl 存储和压缩 Moose 对象?

java - 如何使用 Gzip (Deflate) 创建高度可压缩的文件?

Python 为 "perl -pe",对 stdin 中的每一行执行 Python 命令

sql - sybase更新越来越慢

Linux - 如何在不提取内容并再次应用 tar 的情况下重命名 .tgz 文件中的文件?