您只是缺少binmode(F); 或:raw IO 层。这些导致 Perl 完全按照它在磁盘上显示的方式返回文件。没有行尾翻译。不解码字符编码。
open(my $fh, '<:raw', $file)
or die "open $file: $!\n");
那么你的代码就可以正常工作了。
my $size = 0;
$size += length while <$fh>;
这不是特别好,因为它可以一次读取整个文件以获取二进制文件。所以让我们改为读取固定大小的块。
local $/ = \(64*1024);
my $size = 0;
$size += length while <$fh>;
这与使用read 基本相同,它一次读取 4K 或 8K(在较新的 Perls 中)。一次阅读更多内容对性能有好处,我们可以使用sysread 来做到这一点。
my $size = 0;
while (my $bytes_read = sysread($fh, my $buf, 64*1024)) {
$size += $bytes_read;
}
不过,阅读整个文件很愚蠢。您可以直接搜索到文件的末尾。
use Fcntl qw( SEEK_END );
my $size = sysseek($fh, 0, SEEK_END);
但话又说回来,您不妨使用-s。
my $size = -s $fh;