对从Perl中的文件读取感到困惑

时间:2013-07-17 10:28:34

标签: performance perl file io

当我想从文件中读取时,我使用以下代码:

open my $fh, "file_path";
while(<$fh>)
{
    # do something here
}

但是如果文件非常大,我担心IO性能,因为它逐行读取磁盘。

在C程序中,我们可能更喜欢一次将几个字节(例如:4096字节)读入内存(调用'fread'函数)。这可以减少磁盘IO操作的数量,并有利于程序的性能。

所以我的问题是:在Perl中有没有办法一次从文件中读取多行或几个字节?或Perl将封装IO细节,我不需要担心吗?

3 个答案:

答案 0 :(得分:5)

是的,默认情况下,IO已缓存,请参阅openperliol

您可以使用sysopen&amp; sysread如果您想要访问C风格的函数。

答案 1 :(得分:3)

当您使用open打开文件时,文件句柄和物理资源之间会有各种层。这些层可以是缓冲(可以关闭输出文件句柄)或PerlIO层。

PerlIO层可以进行编码或行结束转换。例如。要打开一个UTF-8编码的文件,我们会

use autodie; # throw fatal exception when open fails
open my $fh, "<:utf8", $filename;

在打开模式后,可以在:layer打开时指定图层。 :uft8 - 图层是:encoding(uft8)的快捷方式。也可以通过binmode添加图层。

如果你想从这样的文件句柄读取固定长度的字符串到缓冲区,你可以使用非常C-ish read

如果您希望对文件进行无缓冲访问,则可以使用sysopen / sysread,但您不太可能遇到这样的情况。在这种情况下,您无法使用图层,这会吸引文本数据。

如果您只想一次读取整个文件,则应使用针对此用例优化的File::Slurp模块。但对于常规的逐行处理,readline运算符<$fh>已经足够了。

答案 2 :(得分:2)

默认情况下,Perl中的所有I / O操作都是缓冲的。 缓冲可以最大限度地提高I / O操作的吞吐量。除非您需要特殊处理,否则不要乱用它,因为更改默认设置会减慢您的程序。