Perl6:大的压缩文件逐行读取

问题描述 投票:7回答:2

我试图在Perl6中逐行读取gz文件,但是,我被阻止了:

  1. [How to read gz file line by line in Perl6然而,这种方法将所有内容读入:out都使用了太多的RAM,除了很小的文件以外,无法使用。

  2. 我不理解如何使用Perl6的Compress::Zlib逐行获取所有内容,尽管我在他们的github https://github.com/retupmoca/P6-Compress-Zlib/issues/17上打开了一个问题。

  3. 我正在尝试Perl5的Compress::Zlib来翻译此代码,该代码在Perl5中非常有效:

  4. 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();

但是我看不到如何翻译:(

  1. 我对Lib :: Archive示例https://github.com/frithnanth/perl6-Archive-Libarchive/blob/master/examples/readfile.p6感到困惑,在这里我看不到如何获得第3项内容

  • 应该有类似的东西>]

  • [for $file.IO.lines(gz) -> $line {或类似Perl6的东西,如果存在,我找不到。

    如何在不将所有内容都读入Perl6的RAM的情况下逐行读取大文件?

    我试图在Perl6中逐行读取gz文件,但是,我被阻止了:但是如何在Perl6中逐行读取gz文件,但是这种方法将所有内容读入:out会占用过多的RAM到...

    更新

    现在经过测试,发现了一个错误,现在已解决。

    解决方案2

    use Compress::Zlib;
    
    my $file   = "data.txt.gz" ;
    my $handle = try open $file or die "Error reading $file: $!" ;
    my $zwrap  = zwrap($handle, :gzip) ;
    
    for $zwrap.lines {
        .print
    }
    
    CATCH { default { die "Error reading $file: $_" } }
    
    $handle.close ;
    

    我已经用一个小的压缩文本文件进行了测试。

    我对gzip等了解不多,但是基于以下原因发现了这一点:

    • 知道P6;

    • 读取Compress::Zlib's README并选择Compress::Zlib例程;

    • 查看模块的源代码,特别是README zwrap;]的签名

    • 反复试验,主要是为了猜测我需要传递the zwrap routine副词。


    • 请评论我的代码是否适合您。我猜最主要的是它对您拥有的大文件是否足够快。

      尝试失败的解决方案#5

      在解决方案#2正常工作的情况下,我希望能够写出:

    zwrap

    但是失败了:

    our sub zwrap ($thing, :$zlib, :$deflate, :$gzip)

    大概是因为此模块是在重组:gzip类之前编写的。

    导致我进入use Compress::Zlib ; .print for "data.txt.gz".&zwrap(:gzip).lines ; 。我注意到没有回应,也没有在No such method 'eof' for invocant of type 'IO::Path' 上看到相关的回购。

    我专注于您尝试的IO解决方案。

    对于@MattOates' IO::Handle like object with .lines ? issue的调用:IO::Handle似乎试图返回从zip文件.lines读取的行(被视为输出参数,但它不是真正的Perl 5参考变量[1 ]

    ),但修改后的值不会返回到Perl 6脚本中。

    以下是可能的解决方法:在curent目录中创建包装器模块,例如./ MyZlibWrapper.pm

    https://github.com/MattOates?tab=repositories

    然后在此包装模块上使用Inline::Perl5,而不是Inline::Perl5。例如./ p.p​​6

    $gz.gzreadline($_)

    [1]在Perl 5中,您可以修改不是引用的输入参数,并且更改将反映在调用方中。这可以通过修改特殊gzreadline数组变量中的条目来完成。例如:即使未通过引用传递gzreadlineby modifying its input argument $_也会引用$_

    gzip perl6 raku
    2个回答
    7
    投票

    更新


    5
    投票

    我专注于您尝试的IO解决方案。

    对于@MattOates' IO::Handle like object with .lines ? issue的调用:IO::Handle似乎试图返回从zip文件.lines读取的行(被视为输出参数,但它不是真正的Perl 5参考变量[1 ]

    ),但修改后的值不会返回到Perl 6脚本中。
    © www.soinside.com 2019 - 2024. All rights reserved.