在Perl中将文件读入变量

17

那不是好的代码。这个更好:open(my $fh, "< :encoding(UTF-8)", "input.text") || die "can't open input.text: $!"; $content = do { local $/; <$fh> }; close($fh) || die "can't close input.text: $!"; - tchrist
3个回答

39

我认为常见做法是这样的:

    my $content;
    open(my $fh, '<', $filename) or die "cannot open file $filename";
    {
        local $/;
        $content = <$fh>;
    }
    close($fh);

使用三个参数的open更加安全。将文件句柄作为变量使用是现代Perl应该使用的方式,而使用local $/可以在块结束时恢复$/的初始值,而不是硬编码的\n


1
请见 http://search.cpan.org/dist/File-Slurp/extras/slurp_article.pod。 - Sinan Ünür
1
请问您能解释一下 local $/ 的作用是什么吗?这个问题在谷歌上不太好搜索 :) - Miroslav Popov
1
@MiroslavPopov,$/$INPUT_RECORD_SEPARATOR相同。perlvar文档涵盖了它。具体来说,它使$content = <$fh>能够读取整个文件,而不仅仅是第一行。 - n0rd
@n0rd,谢谢。local $/; 实际上是 local $/ = undef;,这会欺骗 <FH> 读取完整文件。这样做正确吗?(Perl 不是 .NET。我们必须阅读未写的内容。) - Miroslav Popov

16
use File::Slurp;
my $content = read_file( 'input.txt' ) ;

6
我不赞同仅为了打开和读取文件而加载一个模块。能够打开和读取文件是太基本的操作,必须非常非常熟悉才行。 - tchrist
20
当一个模块可以完成同样的任务时,我反对不停地重复写相同的五行代码。 - Quentin
7
这甚至不是一个标准模块。这会降低代码的可移植性。 - tchrist
6
生成Makefile时使用依赖项是为了确保正确性。请注意,不要改变原意。 - Quentin

3
请注意,如果您处于可以安装模块的环境中,您可能希望使用IO::All
use IO::All;
my $contents;
io('file.txt') > $contents;

一些可能性有点疯狂,但它们也可以非常有用。


1
一个非标准模块再加上一个巧妙地重载了 > 运算符,仅仅是为了读取一个文件,这似乎有些过头了。每个 Perl 程序员都应该能够轻松完成这个任务,不需要如此复杂的操作。 - tchrist
1
tchrist,重载并不是问题,将HTTP与本地文件访问混为一谈(例如PHP的readfile才是。但是为什么要对CPAN模块进行攻击呢?它们是Perl的优势,不利用它们是愚蠢的。甚至还发明了一个反感它们的战斗术语,这肯定不是好事。 - daxim

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