perl 中的标量变量有任何限制吗?

Is there any limit for scalar variable in perl?

现在我正在处理大于 (1.5 GB) 的大文件。所以我用了File::Map。当输入大于 2.1 GB 脚本失败并显示错误 Use of uninitialized value $count in print at file.pl line 16..

但是脚本是运行2.1GB and below 2.1GB

我的脚本如下

use warnings;
use strict;
use File::Map 'map_file';
my $filename ="/root/Desktop/test_sequence/human_genome";

map_file (my $map,$filename);

my $count;

$count++ while ($map=~/>/g);

print $count; #The file has only 14 `>` so result is 14.

同时我在没有模块的情况下试了一下。它也以同样的错误终止。

use warnings;
use strict;
my $filename ="/root/Desktop/test_sequence/human_genome";

open my $fh,"<",$filename or die "$!";

my $m = do{local $/; <$fh>};

my $count;

$count++ while ($m=~/>/g);

print $count;

不知道这里有什么问题?

问题确实是最大标量大小。理论上它可以在 32 位 perl 上达到 4 GB,但是由于您的地址 space 被限制为容纳 OS 之类的东西,2-3.5 GB 通常是真正的限制。使用 64 位 OS 和 perl 它应该可以工作。

See this answer一些细节。

编辑:在这里工作正常,Fedora 上的 perl 5.22.2,x86_64-linux-thread-multi:

$ dd if=/dev/zero of=zero bs=1M count=5000
5000+0 records in
5000+0 records out
5242880000 bytes (5.2 GB) copied, 34.8694 s, 150 MB/s
$ perl -e 'sub wat{open my $fh, ">>zero" or die $!;
   seek($fh,shift,0); syswrite($fh, ">");}
   wat(1000);
   wat(100_000_000);
   wat(4_500_000_000);'
$ time perl map.pl 
3
real    0m5.638s
user    0m3.921s
sys     0m1.717s

您在几个地方之一达到了有符号 32 位整数限制

32 位有符号值允许从 0x1000_00000x7FFF_FFFF 的值,即 -2,147,483,648 到 2,147,483,647。因此您的 2.1GB 限制

我不知道这是否是您构建的 perl 的限制,或者它是否是 File::Map

的一部分

任何大小的文件都可以通过一次读取一行来非常简单地处理,并且由于您的目的似乎只是计算 Unicode GREATER-THAN SIGN 字符的数量,您可以很容易地做到这一点这个

use strict;
use warnings;

use constant HUMAN_GENOME => '/root/Desktop/test_sequence/human_genome';

my $count = do {

    open my $fh, '<', HUMAN_GENOME or die sprintf qq{Unable to open "%s": $!}, HUMAN_GENOME;

    my $n = 0;

    $n += tr/>// while <$fh>;

    $n;
};

print $count;