在Perl中,将文件读入字符串的最佳方法是什么?

55

是的,有多种方法可以做到这一点,但必须有一个规范的、最有效的、最简洁的方法。我会添加我所知道的答案,然后看看哪个能脱颖而出。

明确一下,问题是如何最好地将文件内容读入字符串中。 每个答案提供一种解决方案。

17个回答

6

对于一行命令,通常可以使用-0开关(与-n一起使用)使perl一次性读取整个文件(如果文件不包含任何空字节):

perl -n0e 'print "content is in $_\n"' filename

如果是二进制文件,你可以使用-0777
perl -n0777e 'print length' filename

这是一种很好的方法,用于检查文件中尝试进行的行替换是否真正发生:perl -p -i -0 -e 's/^old_line/new_line/m or (print and die)' some_file,或者如果有多个匹配行,则可能需要使用 /mg。 - Britton Kerin

4
看看Perl6::Slurp的概述,它非常灵活,并且只需要很少的努力就可以做到正确。

3

没有人提到过read或sysread,所以这里有一个简单快速的方法:

my $string;
{
    open my $fh, '<', $file or die "Can't open $file: $!";
    read $fh, $string, -s $file;   # or sysread
    close $fh;
}

3

不建议使用链接回答。 将代码复制到您的答案中。 - Gilles Quénot

1

调整特殊的记录分隔符变量$/

undef $/;
open FH, '<', $filename or die "$!\n";
my $contents = <FH>;
close FH;

1

这是最糟糕的做法之一!(请参见评论。)

open(F, $filename) or die "OPENING $filename: $!\n";
@lines = <F>;
close(F);
$string = join('', @lines);

2
这可能是我能想到的最低效的方法,特别是对于大文件来说。现在你有两份相同的数据,并且为了将其加载到标量中,你已经处理了两次。 - Robert Gamble
这完全取决于情况。对于小文件或仅需运行一次的快速脚本,如果没有"$string=cat $filename"可用,这是完全合理的。虽然效率低下,但这并不一定是唯一需要考虑的因素。 - Mr.Ree
1
这个回答不应该被负评。一群不理解或不关心perl中<FILEHANDLE>含义的脚本小子们。它是一个数组,傻瓜。性能不比页面上其他答案差。非常详细地介绍了如何将Perl文件句柄和读入操作视为一个数组。 - unixman83

0
open(IN, "<$filename");
$contents = join('', <IN>);
close(IN);

细节:

<IN> 是一个文件描述符,如果赋值给一个列表变量/上下文,则返回一个行的列表(也称为数组)。

join 接受一个分隔符和一组行,并返回将所有行连接在一起的字符串。来源:https://perldoc.perl.org/functions/join)。

open 以"<"作为文件名前缀,以读取模式打开文件。

我经常使用 join 结构来处理一行代码,例如 perl -e '$_=join("",<>);s/multiline_regex/replacement_string/gms;print'。m/s 选项支持多行正则表达式,请参阅 https://perldoc.perl.org/perlre


2
回答需要支持信息 您的回答可以通过提供更多的支持信息来改进。请[编辑]以添加进一步的细节,例如引用或文档,以便他人可以确认您的回答是否正确。您可以在帮助中心找到关于如何撰写良好回答的更多信息。 - moken
2
回答需要支持信息 您的回答可以通过提供更多的支持信息来改进。请[编辑]以添加进一步的细节,例如引用或文档,以便他人可以确认您的回答是否正确。您可以在帮助中心找到关于如何撰写良好回答的更多信息。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接