这里我们简要概述了与文件相关的输入/输出操作。详细信息可以在 IO
角色的文档中找到,以及 IO::Handle
和 IO::Path
类型。
从文件读取§
读取文件内容的一种方法是通过 open
函数使用 :r
(读取)文件模式选项打开文件,并吸入内容
my = open "testfile", :r;my = .slurp;.close;
这里我们使用 IO::Handle
对象上的 close
方法显式地关闭文件句柄。这是读取文件内容的一种非常传统的方式。但是,可以使用以下更简单明了的方式来完成相同操作
my = "testfile".IO.slurp;# or in procedural form:= slurp "testfile"
通过将 IO
角色添加到文件名字符串,我们实际上能够将字符串本身视为文件对象,从而直接吸入其内容。请注意,slurp
会为您处理打开和关闭文件。
逐行§
我们还可以选择逐行读取文件。换行符(例如,$*IN.nl-in
)将被排除在外。
for 'huge-csv'.IO.lines -># or if you'll be processing latermy = 'huge-csv'.IO.lines;
写入文件§
要将数据写入文件,我们同样可以选择使用传统的调用open
函数的方法——这次使用:w
(写入)选项——并将数据打印到文件中
my = open "testfile", :w;.print("data and stuff\n");.close;
或者等效地使用say
,因此不再需要显式换行符
my = open "testfile", :w;.say("data and stuff");.close;
我们可以使用spurt
来简化此操作,它将以写入模式打开文件,将数据写入文件并为我们关闭文件
spurt "testfile", "data and stuff\n";
默认情况下,所有(文本)文件都以 UTF-8 编码写入,但是如果需要,可以通过:enc
选项指定显式编码
spurt "testfile", "latin1 text: äöüß", enc => "latin1";
要将格式化的字符串写入文件,请使用printf函数,该函数属于IO::Handle
。
my = open "testfile", :w;.printf("formatted data %04d\n", 42);.close;
要追加到文件,请在显式打开文件句柄时指定:a
选项,
my = open "testfile", :a;.print("more data\n");.close;
或者等效地使用say
,因此不再需要显式换行符,
my = open "testfile", :a;.say("more data");.close;
或者更简单地使用spurt
调用中的:append
选项
spurt "testfile", "more data\n", :append;
要将二进制数据显式写入文件,请使用:bin
选项打开它。然后,输入/输出操作将使用Buf
类型而不是Str
类型进行。
复制、重命名和删除文件§
copy
、rename
、move
和unlink
例程可用于避免使用低级系统命令。有关详细信息,请参阅copy、rename、move和unlink。以下是一些示例
my = 'foo';my = 'foo.bak';my = '/disk1/foo';# note 'diskN' is assumed to be a physical storage devicecopy , ; # overwrites $fileb if it existscopy , , :createonly; # fails if $fileb existsrename , 'new-foo'; # overwrites 'new-foo' if it existsrename , 'new-foo', :createonly; # fails if 'new-foo' exists# use move when a system-level rename may not workmove , '/disk2/foo'; # overwrites '/disk2/foo' if it existsmove , '/disk2/foo', :createonly; # fails if '/disk2/foo' existsunlink ;.IO.unlink;
两个unlink
语句如果存在,则删除其参数,除非用户没有正确的权限这样做;在这种情况下,它会引发异常。
检查文件和目录§
对IO::Handle
对象使用e
方法来测试文件或目录是否存在。
if "nonexistent_file".IO.eelse
也可以使用冒号对语法来实现相同的功能
if "path/to/file".IO ~~ :e
my = "path/to/file";if .IO ~~ :e
类似于文件存在性检查,还可以检查路径是否为目录。例如,假设文件testfile
和目录lib
存在,我们将从存在性测试方法e
获得相同的结果,即两者都存在
say "testfile".IO.e; # OUTPUT: «True»say "lib".IO.e; # OUTPUT: «True»
但是,由于它们中只有一个是目录,因此目录测试方法d
将给出不同的结果
say "testfile".IO.d; # OUTPUT: «False»say "lib".IO.d; # OUTPUT: «True»
当然,如果我们通过文件测试方法f
检查路径是否为文件,则情况就会发生变化
say "testfile".IO.f; # OUTPUT: «True»say "lib".IO.f; # OUTPUT: «False»
还有其他方法可用于查询文件或目录,其中一些有用的方法是
my = "file";say .IO.modified; # return time of last file (or directory) changesay .IO.accessed; # return last time file (or directory) was readsay .IO.s; # return size of file (or directory inode) in bytes
有关更多方法和详细信息,请参阅IO::Path
。
获取目录列表§
要列出当前目录的内容,请使用dir
函数。它返回一个IO::Path
对象的列表。
say dir; # OUTPUT: «"/path/to/testfile".IO "/path/to/lib".IO»
要列出给定目录中的文件和目录,只需将路径作为参数传递给dir
say dir "/etc/"; # OUTPUT: «"/etc/ld.so.conf".IO "/etc/shadow".IO ....»
创建和删除目录§
要创建新目录,只需使用目录名称作为参数调用mkdir
函数
mkdir "newdir";
该函数在成功时返回创建的目录的名称,在失败时返回Nil
。因此,标准 Perl 惯用法按预期工作
mkdir "newdir" or die "$!";
使用rmdir
删除空目录
rmdir "newdir" or die "$!";