【发布时间】:2019-02-21 18:21:34
【问题描述】:
我正在尝试在 Perl6 中逐行读取 gz 文件,但是我被阻止了:
How to read gz file line by line in Perl6 然而,这种将所有内容读入
:out的方法使用的 RAM 太多,无法使用,除非是非常小的文件。我不明白如何使用 Perl6 的
Compress::Zlib逐行获取所有内容,尽管我在他们的 github https://github.com/retupmoca/P6-Compress-Zlib/issues/17 上打开了一个问题我正在尝试 Perl5 的
Compress::Zlib来翻译这段代码,它在 Perl5 中完美运行:
use Compress::Zlib; my $file = "data.txt.gz"; my $gz = gzopen($file, "rb") or die "Error reading $file: $gzerrno"; while ($gz->gzreadline($_) > 0) { # Process the line read in $_ } die "Error reading $file: $gzerrno" if $gzerrno != Z_STREAM_END ; $gz->gzclose() ;
在 Perl6 中使用 Inline::Perl5 处理类似的事情:
use Compress::Zlib:from<Perl5>;
my $file = 'chrMT.1.vcf.gz';
my $gz = Compress::Zlib::new(gzopen($file, 'r');
while ($gz.gzreadline($_) > 0) {
print $_;
}
$gz.gzclose();
但我看不到如何翻译这个:(
我对 Lib::Archive 示例 https://github.com/frithnanth/perl6-Archive-Libarchive/blob/master/examples/readfile.p6 感到困惑,我不知道如何在这里获得类似于第 3 项的内容
应该有类似
for $file.IO.lines(gz) -> $line { 或 Perl6 中类似的东西,如果它存在,我找不到它。
如何在 Perl6 中逐行读取大文件而不将所有内容都读入 RAM?
【问题讨论】:
-
Re: " using Inline::Perl5":对于
$gz.gzreadline($_)的调用:似乎gzreadline试图通过修改返回从zip文件中读取的行它的输入参数$_(被视为输出参数,但不是真正的 Perl 5 引用变量),但该值不会返回到 Perl 6 脚本。 -
关于 Perl 5
gzreadline函数的更多信息:在 Perl 5 中,您可以修改不是引用的输入参数,更改将反映在调用者中。这是通过修改特殊@_数组变量中的条目来完成的。例如:sub quote { $_[0] = "'$_[0]'" } $str = "Hello"; quote($str)将引用$str,即使$str没有通过引用传递。我不确定Inline::Perl5是否可以处理这类输出参数 -
关于项目#4,只是为了澄清一下:底层库提供了一个
archive_read_data_block(),它是通用的,必须适用于每种存档格式的每种文件。read-file-content方法在Buf中返回整个文件。要逐行读取文件,应该使用Archive::Libarchive::Raw编写自己的方法,但我发现有更简单的方法可以做到这一点,如您的问题的答案所示。