为什么 Perl 的 Archive::Tar 内存不足?

发布于 2024-08-10 03:57:37 字数 308 浏览 10 评论 0原文

我使用下面的 Perl 代码列出 tar 存档中的文件。 tar 存档的大小始终约为 15MB。

my $file = shift;
my $tar = Archive::Tar->new("$file");
my @lists = $tar->list_files;
$tar->error unless @lists;

执行此代码会出现错误“内存不足”。我的 Linux 系统大约有 512MB,我不想增加系统内存。任何人都可以建议我是否可以修改此代码以获得更好的性能或使用其他代码来列出 tar 存档中的文件。

I am using below Perl code to list the files in tar archive. The size of the tar archive is always about 15MB.

my $file = shift;
my $tar = Archive::Tar->new("$file");
my @lists = $tar->list_files;
$tar->error unless @lists;

Executing this code gives me an error "Out of Memory". I have about 512MB in my Linux system and I dont want to increase the memory of my system. Can anyone please suggest me if this code can be modified for better performance or another code to list the files in tar archive.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

泅人 2024-08-17 03:57:37

来自 Archive::Tar 常见问题解答

Archive::Tar 不是很慢吗?
是的。它是纯 perl,所以它比 /bin/tar 慢很多,但是它非常便携。如果速度是一个问题,请考虑使用 /bin/tar。

Archive::Tar 不是比 /bin/tar 占用更多内存吗?
是的,请参阅之前的答案。由于 Compress::Zlib 和 IO::Zlib 不支持在其文件句柄上查找,因此除了将存档读入内存之外别无选择。如果您想对存档进行内存中操作,这是可以的。

如果您只想提取,请使用 extract_archive 类方法。它将立即优化并写入磁盘。

另一种选择是使用 iter 类方法来迭代 tarball 中的文件,而不是一次将它们全部读取到内存中。

 

因此,根据上述内容,这应该是解决方案(未经测试):

my $next = Archive::Tar->iter( $file );

while ( my $f = $next->() ) {
    say $f->name;
}

/I3az/

From Archive::Tar FAQ:

Isn't Archive::Tar slow?
Yes it is. It's pure perl, so it's a lot slower then your /bin/tar However, it's very portable. If speed is an issue, consider using /bin/tar instead.

Isn't Archive::Tar heavier on memory than /bin/tar?
Yes it is, see previous answer. Since Compress::Zlib and therefore IO::Zlib doesn't support seek on their filehandles, there is little choice but to read the archive into memory. This is ok if you want to do in-memory manipulation of the archive.

If you just want to extract, use the extract_archive class method instead. It will optimize and write to disk immediately.

Another option is to use the iter class method to iterate over the files in the tarball without reading them all in memory at once.

 

So based on above then this should be the solution (untested):

my $next = Archive::Tar->iter( $file );

while ( my $f = $next->() ) {
    say $f->name;
}

/I3az/

败给现实 2024-08-17 03:57:37

我在一个大焦油上尝试过,也遇到了错误。可能是库中的错误。
以下对我有用:

@files = split/\n/, `tar tf $file`

I tried that on a large tar and got an error too. Probably a bug in libs.
The following worked for me:

@files = split/\n/, `tar tf $file`
网名女生简单气质 2024-08-17 03:57:37

如果 Perl 不是必须的,请使用 tar

$ tar tvf file.tar

if Perl is not a must, use tar

$ tar tvf file.tar
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文