是的,有多种方法可以做到这一点,但必须有一个规范的、最有效的、最简洁的方法。我会添加我所知道的答案,然后看看哪个能脱颖而出。
明确一下,问题是如何最好地将文件内容读入字符串中。 每个答案提供一种解决方案。
是的,有多种方法可以做到这一点,但必须有一个规范的、最有效的、最简洁的方法。我会添加我所知道的答案,然后看看哪个能脱颖而出。
明确一下,问题是如何最好地将文件内容读入字符串中。 每个答案提供一种解决方案。
这个怎么样?
use File::Slurp;
my $text = read_file($filename);
注:注意File-Slurp的漏洞#83126:编码(UTF-8)存在安全隐患。 我现在建议使用File::Slurper(免责声明:我写了它),因为它在编码方面有更好的默认设置:
use File::Slurper 'read_text';
my $text = read_text($filename);
或者Path::Tiny:
use Path::Tiny;
path($filename)->slurp_utf8;
我喜欢使用do
块来做这件事,其中我将@ARGV
本地化,以便我可以使用钻石操作符为我执行文件操作。
my $contents = do { local(@ARGV, $/) = $file; <> };
my $contents = do {
open my $fh, '<:encoding(UTF-8)', $file or die '...';
local $/;
<$fh>;
};
如果您不需要更改文件,您可以使用File::Map。
my $contents = do {local (@ARGV,$/) = $file; <>};
,这与原来的意思完全相同,但使用更少的字符 :) - ephemient<>
来从标准输入读取数据,但是我却期望它从文件中读取。<>
的行为在第一次调用和后续调用时有所不同,而由于我改变了第一次调用的方式,也就改变了现有调用的行为(它原本期望的是<>
的标准输入行为)。 - Adam Millerchip在编写文件读取的操作时,使用File::Slurp是最佳方式。Uri Guttman对多种文件读取方式进行了深入研究,并记录了他的发现和总结,并将其纳入了File::Slurp。
open(my $f, '<', $filename) or die "OPENING $filename: $!\n";
$string = do { local($/); <$f> };
close($f);
需要考虑的事项(特别是与其他解决方案相比):
因此,我得到:
my $contents = do {
local $/;
open my $fh, $filename or die "Can't open $filename: $!";
<$fh>
};
我并不是魔术的粉丝,除非真正使用魔术。与其伪装,为什么不直接使用open调用呢?这并不需要更多工作,而且更加明确。(真正的魔术,特别是处理“-”时,要完美模拟则需要更多的工作,但我们在这里并没有使用它。)
mmap(内存映射)字符串可以在以下情况下很有用:
#!/usr/bin/perl
use warnings; use strict;
use IO::File;
use Sys::Mmap;
sub sip {
my $file_name = shift;
my $fh;
open ($fh, '+<', $file_name)
or die "Unable to open $file_name: $!";
my $str;
mmap($str, 0, PROT_READ|PROT_WRITE, MAP_SHARED, $fh)
or die "mmap failed: $!";
return $str;
}
my $str = sip('/tmp/words');
print substr($str, 100,20);
更新:2012年5月
在将Sys::Mmap替换为File::Map后,以下内容应该基本等同。
#!/usr/bin/perl
use warnings; use strict;
use File::Map qw{map_file};
map_file(my $str => '/tmp/words', '+<');
print substr($str, 100, 20);
use Path::Class;
file('/some/path')->slurp;
my $contents = `cat $file`;
{
open F, $filename or die "Can't read $filename: $!";
local $/; # enable slurp mode, locally.
$file = <F>;
close F;
}
use IO::All;
# read into a string (scalar context)
$contents = io($filename)->slurp;
# read all lines an array (array context)
@lines = io($filename)->slurp;