ZetCode

Perl 读取文件

最后修改于 2023 年 8 月 24 日

在本文中,我们将介绍如何在 Perl 中读取文件。

要在 Perl 中读取文件,我们可以使用内置的 openread 函数,或者利用 Path::TinyIO::All 等外部模块。

words.txt
sky
water
rock
falcon
cloud
war
nice
cup
wrong
forest
blue
bottle
pen
chair
cup

我们使用一个简单的文本文件。

Perl 读取文本文件 I

在第一个示例中,我们使用 open 和 for 循环读取文本文件的内容。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

open my $fh, "<", "words.txt"
    or die "cannot open file $!";

print $_ for <$fh>;

close $fh;

我们逐行读取文件内容。

open my $fh, "<", "words.txt"
    or die "cannot open file $!";

使用 open 函数,我们以只读模式打开文件句柄到指定文本文件。

print $_ for <$fh>;

我们通过 for 循环遍历文件句柄,并逐行打印文件内容。

close $fh;

最后,我们使用 close 关闭句柄。

$ ./main.pl
sky
water
rock
falcon
cloud
war
nice
cup
wrong
forest
blue
bottle
pen
chair

Perl 读取文本文件 II

第二个示例使用 while 循环读取文本文件。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

open my $fh, "<", "words.txt"
    or die "cannot open file $!";

while (<$fh>) {

    print $_;
}

close $fh;

使用 while 循环和 <> 操作符,我们逐行读取文件。

Perl 钻石操作符

Perl 允许在不显式打开文件的情况下读取文件。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

while (<>) {

    print $_;
}

钻石操作符 (<>) 将查看 @ARGV 以查找要打开和处理的文件。

$ ./main.pl words.txt
sky
water
rock
falcon
cloud
war
nice
cup
wrong
forest
blue
bottle
pen
chair
cup

我们将文件名作为参数传递给 Perl 程序。

Perl 读取整个文本文件

对于相对较小的文件,我们可以一次性将整个文件读取到一个变量中。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;
use Path::Tiny;

my $f = path('./words.txt');

my $res = $f->slurp;

print($res);

在示例中,我们使用了 Path::Tiny 模块。

my $f = path('./words.txt');

我们创建一个路径对象。

my $res = $f->slurp;

我们使用 slurp 将内容读取到一个变量中。

Perl 将文本文件读入数组

在下一个示例中,我们将文本文件读入一个数组。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;
use Path::Tiny;

my $f = path('./words.txt');

my @lines = $f->lines;

print $_ for (@lines);

在程序中,我们使用 Path::Tiny 及其 lines 成员函数。

Perl head/tail 示例

在下一个示例中,我们创建一个 head/tail 工具。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;
use Path::Tiny;

my $f = path('./words.txt');
my $n = shift || 5;

my @lines = $f->lines( { count => $n } );
print $_ for (@lines);

该程序从文本文件的顶部或底部读取 n 行。

my $n = shift || 5;

我们在命令行中提供要读取的行数。如果不提供任何值,则从顶部读取五行。

my @lines = $f->lines( { count => $n } );

要读取的行数通过 count 选项提供。它也接受负整数。

$ ./main.pl 3
sky
water
rock
$ ./main.pl
sky
water
rock
falcon
cloud
$ ./main.pl -2
chair
cup

Perl 读取网页

在下一个示例中,我们读取一个远程文件(网页资源)。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;
use HTTP::Tiny;

my $url = 'http://webcode.me/small.txt';

my $r = HTTP::Tiny->new->get($url);

if ($r->{success}) {

    my $content = $r->{content};
    print($content);
}

为了读取资源,我们使用了 HTTP::Tiny 模块。

$ ./main.pl
small text page

Perl 读取二进制文件

下面的示例读取一个二进制文件并以十六进制格式打印其内容。

main.pl
#!/usr/bin/perl

use v5.34.0;
use warnings;

open my $fh, "<:raw", "favicon.ico"
  or die "cannot open file $!";

my $block_size = 1024;
my $data;
my $n = 1;

while ( read $fh, $data, $block_size ) {

    my @res = split( //, $data );

    foreach (@res) {

        printf( "%02x ", ord($_) );
        $n++;

        if ( $n > 20 ) {
            print("\n");
            $n = 1;
        }

    }
}

print "\n";

close $fh;

该程序读取一个小的图标。我们利用了 openreadsplit 函数。

open my $fh, "<:raw", "favicon.ico"
    or die "cannot open file $!";

我们以原始模式打开文件进行读取。

while ( read $fh, $data, $block_size ) {

在 while 循环中,我们以 1024 字节的块将数据读取到缓冲区中。

my @res = split( //, $data );

foreach (@res) {

    printf( "%02x ", ord($_) );
    $n++;

    if ( $n > 20 ) {
        print("\n");
        $n = 1;
    }
}

我们将原始行拆分成字节,并以十六进制格式打印它们。每行有 20 个字节。

$ ./main.pl
00 00 01 00 01 00 10 10 00 00 00 00 00 00 68 05 00 00 16 00
00 00 28 00 00 00 10 00 00 00 20 00 00 00 01 00 08 00 00 00
00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
00 00 00 00 00 00 ff ff ff 00 4d 45 3d 00 00 00 00 00 00 00
...

在本文中,我们已在 Perl 中读取了文本和二进制文件。

作者

我叫 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教学编程方面拥有超过十年的经验。

列出 所有 Perl 教程