当前位置: 首页 > 知识库问答 >
问题:

perl6:一行一行读取大的gzip文件

韶亮
2023-03-14

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

>

  • 如何在Perl6中逐行读取gz文件,但是,这种方法将所有内容读入:out会使用太多的RAM,除了在非常小的文件上之外,它都不可用。

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

    我正在尝试用Perl5的< code>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 example搞糊涂了https://github . com/frith nanth/perl 6-Archive-Lib Archive/blob/master/examples/readfile . P6我看不出我如何能在这里得到类似于第3项的东西

    应该有这样的内容

    $file.IO的<code>。线(gz)-

    如何在 Perl6 中逐行读取大文件而不将所有内容读入 RAM?

  • 共有2个答案

    郜俊晤
    2023-03-14

    我专注于您尝试的Inline::Perl5解决方案。

    对于$gz.gzreadline($_)的调用:似乎gzreadline试图通过修改其输入参数$_(被视为输出参数,但它不是真正的Perl 5引用变量[1])来返回从zip文件读取的行,但修改后的值没有返回到Perl 6脚本。

    这里有一个可行的解决方法:在当前目录中创建一个包装器模块,例如。/MyZlibWrapper.pm:

    package MyZlibWrapper;
    use strict;
    use warnings;
    use Compress::Zlib ();
    use Exporter qw(import);
    
    our @EXPORT = qw(gzopen);
    our $VERSION = 0.01;
    
    sub gzopen {
        my ( $fn, $mode ) = @_;
        my $gz = Compress::Zlib::gzopen( $fn, $mode );
        my $self = {gz => $gz}; 
        return bless $self, __PACKAGE__;
    }
    
    sub gzreadline {
        my ( $self ) = @_;
        my $line = "";
        my $res = $self->{gz}->gzreadline($line);
        return [$res, $line];
    }
    
    sub gzclose {
        my ( $self ) = @_;
        $self->{gz}->gzclose();
    }    
    
    1;
    

    然后在此包装器模块上使用Inline::Perl5而不是Compress::Zlib。例如/p.p6:

    use v6;
    use lib:from<Perl5> '.';
    use MyZlibWrapper:from<Perl5>;
    my $file = 'data.txt.gz';
    my $mode = 'rb';
    my $gz = gzopen($file, $mode);
    loop {
        my ($res, $line) = $gz.gzreadline();
        last if $res == 0;
        print $line;
    }
    $gz.gzclose();
    

    [1] 在 Perl 5 中,您可以修改不是引用的输入参数,更改将反映在调用方中。这是通过修改特殊 @_ 数组变量中的条目来完成的。例如:子引号 { $_[0] = “'$_[0]'” } $str = “Hello”; 引号($str)将引用$str即使$str未通过引用传递。

    慕震博
    2023-03-14

    更新现已测试,显示错误,现已修复。

    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文本文件测试了这一点。

    对gzip等不太了解。但是基于以下几点得出了这个结论:

    >

  • 知道P6;

    读取Compress::ZlibREADME,并选择zwrap例程;

    查看模块的源代码,特别是zwrap例程的签名,我们的子zwrap($thing,$zlib,$deflate,$gzip)

    而反复试验,主要是猜测我需要传递:gzip副词。

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

    随着解决方案#2的工作,我本来希望能够写:

    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类似于带有的对象。哪些行?问题我注意到没有回应,也没有看到相关的回购https://github.com/MattOates?tab=repositories.

  •  类似资料:
    • 我想逐行读取一个文件,但不完全加载到内存中。 我的文件太大,无法在内存中打开,如果尝试这样做,我总是会出现内存错误。 文件大小为1 GB。

    • 我试图在Perl6中逐行读取一个巨大的gz文件。 我正在尝试做这样的事情 但是这会给出一个错误,我有一个格式不正确的UTF-8。我看不到如何从帮助页面读取gzip材料https://docs.perl6.org/language/unicode#UTF8-C8或https://docs.perl6.org/language/io 我想完成和在Perl5中一样的事情:http://blog-en .

    • 我可以使用Apache POI只读取Excel文件的第一行吗?我不想读取整个文件,因为它有50,000行,读取最多需要10分钟(性能是一场灾难)。我通过文件上传获取字节。我的选项是字节数组或InputStream。现在我正在这样做:

    • 问题内容: 我有一个大文件,需要阅读并制作字典。我希望尽快。但是我在python中的代码太慢了。这是显示问题的最小示例。 首先制作一些假数据 现在,这里是一个最小的python代码片段,可以读入它并制作一个字典。 时间: 但是,可以更快地读取整个文件,如下所示: 我的CPU有8个核心,是否可以在python中并行化此程序以加快速度? 一种可能是读取大块输入,然后在不同的非重叠子块上并行运行8个进程

    • 问题内容: 我只想读取文本文件的第一行并将该第一行放在字符串数组中。 这就是我所拥有的,但是它读取了整个文件。 myTextFile中的ex文本: 问题答案: 如果我了解你,那

    • 本文向大家介绍C++实现一行一行读取文本的方法,包括了C++实现一行一行读取文本的方法的使用技巧和注意事项,需要的朋友参考一下 如下所示: 以上这篇C++实现一行一行读取文本的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持呐喊教程。