【问题标题】:Puzzled about reading from files in Perl对在 Perl 中读取文件感到困惑
【发布时间】:2013-07-15 20:41:23
【问题描述】:

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

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

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

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

所以我的问题是:有没有办法在 Perl 中一次从文件中读取多行或多个字节?还是 Perl 会封装 IO 的细节,我就不用操心了?

【问题讨论】:

  • 你可以阅读关于read函数的文档
  • 过早优化?您是否尝试过使用正常方式?是不是太慢了?
  • 似乎没有人提到$/ = \4096;

标签: performance perl file io


【解决方案1】:

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

如果您想访问 C 风格的函数,可以使用 sysopensysread

【讨论】:

  • 很抱歉接受了另一个更详细的答案,但您的回复确实对我有很大帮助。谢谢!
【解决方案2】:

当您使用open 打开文件时,文件句柄和物理资源之间存在不同的层。这些层可以是缓冲层(可以为输出文件句柄关闭)或 PerlIO 层。

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

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

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

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

如果您想要无缓冲地访问文件,您可以使用sysopen/sysread,但您不太可能遇到这样的情况。在这种情况下,您不能使用图层,这对文本数据很不利。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-03
      • 1970-01-01
      相关资源
      最近更新 更多