读取文件内容的一种方法是通过带有 (读取)文件模式选项的 open 函数打开文件,并吞噬内容:

    这里我们使用 IO::Handle 对象上的 close 方法显式地关闭文件句柄。这是一种非常传统的读取文件内容的方法。但是,同样的事情可像这样更容易和更清楚地完成:

    1. my $contents = "testfile".IO.slurp;
    2. # or in procedural form:
    3. $contents = slurp "testfile"

    通过将 IO 角色添加到文件名字符串中,我们实际上能够将字符串作为文件对象本身引用,从而直接吞噬其内容中。请注意,slurp 负责为你打开和关闭文件。

    逐行读取

    当然,我们也可以选择逐行读取文件。将排除新行分隔符(即 $*IN.nl-in)。

    1. for 'huge-csv'.IO.lines -> $line {
    2. # Do something with $line
    3. }
    4. # or if you'll be processing later
    5. my @lines = 'huge-csv'.IO.lines;

    写文件

    要将数据写入文件,我们再次选择调用 open 函数的传统方法 - 这次使用 :w(write)选项 - 并将数据打印到文件中:

    1. my $fh = open "testfile", :w;
    2. $fh.print("data and stuff\n");
    3. $fh.close;

    或者使用等效的 say,因此不再需要显式的换行符了:

    1. my $fh = open "testfile", :w;
    2. $fh.say("data and stuff");
    3. $fh.close;

    我们可以通过使用 spurt 在写入模式下打开文件,将数据写入文件并再次为我们关闭来简化此操作:

    1. spurt "testfile", "data and stuff\n";

    默认情况下,所有(文本)文件都写为 UTF-8,但是如果需要,可以通过 :enc 选项指定显式编码:

    1. spurt "testfile", "latin1 text: äöüß", enc => "latin1";

    要追加到文件,请在显式地打开文件句柄时指定 :a 选项,

    1. $fh.print("more data\n");
    2. $fh.close;

    或者使用等效的 say,因此不再需要显式的换行符了,

    1. $fh.say("more data");
    2. $fh.close;

    或者甚至在调用 spurt 时加上 :append 选项:

    1. spurt "testfile", "more data\n", :append;

    要将二进制数据显式地写入文件,请使用 :bin 选项打开它。然后输入/输出操作将使用 Buf 类型而不是 Str 类型。

    例程 copy, rename, 和 move 是可用的以避免低级别的系统命令。 在 copy, , 和 move 查看详情. 一些例子:

    1. my $filea = 'foo';
    2. my $fileb = 'foo.bak';
    3. my $filec = '/disk1/foo'; # note 'diskN' is assumed to be a physical storage device
    4. copy $filea, $fileb; # overwrites $fileb if it exists
    5. copy $filea, $fileb, :createonly; # fails if $fileb exists
    6. rename $filea, 'new-foo'; # overwrites 'new-foo' if it exists
    7. rename $filea, 'new-foo', :createonly; # fails if 'new-foo' exists
    8. # use move when a system-level rename may not work
    9. move $fileb, '/disk2/foo'; # overwrites '/disk2/foo' if it exists
    10. move $fileb, '/disk2/foo', :createonly; # fails if '/disk2/foo' exists

    检查文件和目录

    IO::Handle 对象上使用 e 方法来测试文件或目录是否存在。

    1. if "nonexistent_file".IO.e {
    2. say "file exists";
    3. }
    4. else {
    5. say "file doesn't exist";

    也可以使用冒号对语法来实现相同的功能:

    1. if "path/to/file".IO ~~ :e {
    2. }
    3. my $file = "path/to/file";
    4. if $file.IO ~~ :e {
    5. say 'file exists';
    6. }

    与文件存在检查类似,也可以检查路径是否是目录。例如,假设文件 testfile 和目录 lib 存在,我们将从存在测试方法 e 获得相同的结果,即两者都存在:

    1. say "testfile".IO.d; # OUTPUT: «False
    2. »
    3. say "lib".IO.d; # OUTPUT: «True
    4. »

    当我们通过文件测试方法 f 检查路径是否是文件时,结果自然会反过来:

    1. say "testfile".IO.f; # OUTPUT: «True
    2. »
    3. say "lib".IO.f; # OUTPUT: «False
    4. »

    还有其他方法可用于查询文件或目录,一些有用的方法是:

    1. my $f = "file";
    2. say $f.IO.modified; # return time of last file (or directory) change
    3. say $f.IO.accessed; # return last time file (or directory) was read
    4. say $f.IO.s; # return size of file (or directory inode) in bytes

    更多方法和详细信息请查看 IO::Path.

    要列出当前目录的内容,请使用 dir 函数。它返回 IO::Path 对象的列表。

    1. say dir; # OUTPUT: «"/path/to/testfile".IO "/path/to/lib".IO
    2. »

    要列出给定目录中的文件和目录,只需将路径作为参数传递给 dir

    1. say dir "/etc/"; # OUTPUT: «"/etc/ld.so.conf".IO "/etc/shadow".IO ....
    2. »

    创建和移除目录

    要创建一个新目录,只需使用目录名作为参数调用函数 mkdir

      该函数在成功时返回创建目录的名称,在失败时返回 Nil。因此,标准的 Perl 惯用法按预期工作:

      使用 rmdir 来移除*空*目录: