is Cool does IO
IO::Path
是 IO 操作的主力军。
从概念上讲,IO::Path
对象由卷、目录和基本名称组成。它支持纯文本操作和访问文件系统(例如,解析路径或读取文件的所有内容)的操作。
在创建时,每个 IO::Path
对象都会获得有关当前工作目录的信息,该路径可能相对于使用 $.CWD
属性(默认为 $*CWD
)的路径,以及使用特殊 IO::Spec
类型在 $.SPEC
属性中给出的路径操作应使用什么操作系统语义。
$.SPEC
默认为 $*SPEC
的值,它使用适合代码当前运行的操作系统的对象。这是大多数代码都会感到满意的默认值。
在某些情况下(例如测试),您可能希望强制 $*SPEC
使用特定 SPEC 模块之一:IO::Spec::Unix
、IO::Spec::Win32
、IO::Spec::Cygwin
和 IO::Spec::QNX
,或通过快捷方式子类 IO::Path::Unix
、IO::Path::Win32
、IO::Path::Cygwin
和 IO::Path::QNX
创建 IO::Path
对象,这些子类为您预设了 $.SPEC
属性。
除非另有说明,否则本文档的其余部分在其示例中默认采用 Unix 语义。
方法§
方法 new§
multi method new(Str , IO::Spec : = , Str() : = )multi method new(:!, : = '.', : = ''IO::Spec : = , Str() : =)
从路径字符串(正在解析卷、目录名和基本名)或从作为命名参数传递的卷、目录名和基本名创建一个新的 IO::Path
对象。
路径的操作将使用 :$SPEC
语义(默认为当前 $*SPEC
)执行,并将使用 :$CWD
作为路径的相对目录(默认为 $*CWD
)。
如果 $path
包含空字节,它将抛出一个异常,并显示一条消息:“不能将空字符 (U+0000) 用作路径的一部分”。
属性 CWD§
IO::Path.new("foo", :CWD</home/camelia>).CWD.say; # OUTPUT: «/home/camelia»
只读。包含 .new
中 :$CWD
参数的隐式或显式值。
属性 SPEC§
IO::Path.new("foo", :SPEC(IO::Spec::Unix.new))\.SPEC.^name.say; # OUTPUT: «IO::Spec::Unix»
只读。包含 .new
中 :$SPEC
参数的隐式或显式值。
属性 path§
IO::Path.new("foo").path.say; # OUTPUT: «foo»
只读。返回对象构造时的字符串,或者如果使用了 .new
的多部分版本,则返回 $SPEC.join($volume, $dirname, $basename)
的值。注意:这不包括 $.CWD
;有关包括 $.CWD
的字符串化选项,请参见 IO::Path.absolute
和 IO::Path.relative
。
注意:实现可能会缓存使用此属性执行的操作,因此不建议修改其值(通过克隆或代理),否则可能会导致 IO::Path
对象损坏。相反,创建一个新的 IO::Path
对象。
方法 ACCEPTS§
multi method ACCEPTS(IO::Path: Cool --> Bool)
必要时将参数强制转换为 IO::Path
。如果两个路径上的 .absolute
方法返回相同的字符串,则返回 True
。注意:如果两个路径的构造方式不同且从未完全解析,则表面上指向同一资源的两个路径可能不会 smartmatch 为 True
。
say "foo/../bar".IO ~~ "bar".IO # False
原因是上面两个路径在完全解析后可能指向不同的资源(例如,如果 foo
是一个符号链接)。在 smartmatch 之前解析路径以检查它们是否指向同一资源
say "foo/../bar".IO.resolve(:completely) ~~ "bar".IO.resolve(:completely) # True
方法 basename§
method basename(IO::Path:)
返回路径对象的基名部分,它是路径引用的文件系统对象本身的名称。
"docs/README.pod".IO.basename.say; # OUTPUT: «README.pod»"/tmp/".IO.basename.say; # OUTPUT: «tmp»
请注意,在 IO::Spec::Win32
语义中,Windows 共享的 basename
是 \
,而不是共享本身的名称
IO::Path::Win32.new('//server/share').basename.say; # OUTPUT: «\»
方法 add§
method add(IO::Path: Str() --> IO::Path)
将路径片段连接到调用者并返回生成的 IO::Path
。如果将 ../
添加到以文件结尾的路径,则可能需要调用 resolve,以便其他 IO::Path
方法(如 dir 或 open)可以访问生成的路径。另请参阅 sibling 和 parent。
"foo/bar".IO.mkdir;"foo/bar".IO.add("meow") .resolve.relative.say; # OUTPUT: «foo/bar/meow»"foo/bar".IO.add("/meow") .resolve.relative.say; # OUTPUT: «foo/bar/meow»"foo/bar".IO.add("meow.txt").resolve.relative.say; # OUTPUT: «foo/bar/meow.txt»"foo/bar".IO.add("../meow") .resolve.relative.say; # OUTPUT: «foo/meow»"foo/bar".IO.add("../../") .resolve.relative.say; # OUTPUT: «.»method add(IO::Path: * --> IO::Path)
从 Rakudo 编译器的 2021.07 版本开始,还可以指定要添加到路径的多个部分。
"foo".IO.add(<bar baz>).resolve.relative.say; # OUTPUT: «foo/bar/baz»
方法 child§
method child(IO::Path: Str() --> IO::Path)
.add
的别名。
方法 cleanup§
method cleanup(IO::Path: --> IO::Path)
返回一个新路径,它是调用者路径的规范表示形式,清理掉任何无关的路径部分
"foo/./././..////bar".IO.cleanup.say; # OUTPUT: «"foo/../bar".IO»IO::Path::Win32.new("foo/./././..////bar").cleanup.say; "foo\..\bar".IO; # OUTPUT: «"foo\..\bar".IO»
请注意,不会进行任何文件系统访问。另请参阅 resolve
。
方法 comb§
method comb(IO::Path: |args --> Seq)
打开文件并处理其内容的方式与 Str.comb
相同,采用相同的参数。在调用此方法时,实现可能会将文件全部吸入。
方法 split§
method split(IO::Path: |args --> Seq)
打开文件并处理其内容的方式与 Str.split
相同,采用相同参数。在调用此方法时,实现可能会将文件全部吸入。
方法 extension§
multi method extension(IO::Path: --> Str)multi method extension(IO::Path: Int : --> Str)multi method extension(IO::Path: Range : --> Str)multi method extension(IO::Path: Str , Int :, Str : --> IO::Path)multi method extension(IO::Path: Str , Range :, Str : --> IO::Path)
返回由 $parts
部分组成的扩展名(默认为 1
),其中“部分”定义为一个点后跟可能为空的字符串,直到字符串末尾或前一部分。即 "foo.tar.gz"
有一个由两部分组成的扩展名:第一部分是 "gz"
,第二部分是 "tar"
,调用 "foo.tar.gz".IO.extension: :2parts
会得到 "tar.gz"
。如果找不到具有指定数量 $parts
的扩展名,则返回一个空字符串。
$parts
可以是一个 Range
,指定扩展名应具有的最小部分数和最大部分数。该例程将尝试匹配它能匹配的大多数部分。如果 $parts
范围的端点小于 0
,则它们将被视为 0
;实现可能会将大于 2⁶³-1
的端点视为 2⁶³-1
。具有 NaN
或 Str
端点的范围将导致抛出异常。
如果提供了 $subst
,则扩展名将被替换为 $subst
,并返回一个新的 IO::Path
对象。它将使用 $joiner
连接到文件名称,当 $subst
为空字符串时,默认为空字符串,当 $subst
不为空时,默认为 "."
。注意:如果替换的结果是路径的 basename
最终为空,则假定它为 .
(一个点)。
# Getting an extension:say "foo.tar.gz".IO.extension; # OUTPUT: «gz»say "foo.tar.gz".IO.extension: :2parts; # OUTPUT: «tar.gz»say "foo.tar.gz".IO.extension: :parts(^5); # OUTPUT: «tar.gz»say "foo.tar.gz".IO.extension: :parts(0..1); # OUTPUT: «gz»# Replacing an extensionsay "foo.tar.gz".IO.extension: ''; # OUTPUT: «"foo.tar".IO»say "foo.tar.gz".IO.extension: 'ZIP'; # OUTPUT: «"foo.tar.ZIP".IO»say "foo.tar.gz".IO.extension: 'ZIP', :0parts; # OUTPUT: «"foo.tar.gz.ZIP".IO»say "foo.tar.gz".IO.extension: 'ZIP', :2parts; # OUTPUT: «"foo.ZIP".IO»say "foo.tar.gz".IO.extension: 'ZIP', :parts(^5); # OUTPUT: «"foo.ZIP".IO»# Replacing an extension using non-standard joiner:say "foo.tar.gz".IO.extension: '', :joiner<_>; # OUTPUT: «"foo.tar_".IO»say "foo.tar.gz".IO.extension: 'ZIP', :joiner<_>; # OUTPUT: «"foo.tar_ZIP".IO»say "foo.tar.gz".IO.extension: 'ZIP', :joiner<_>,:2parts; # OUTPUT: «"foo_ZIP".IO»say "foo.tar.gz".IO.extension: 'ZIP', :joiner<_>,:parts(^5); # OUTPUT: «"foo_ZIP".IO»# EDGE CASES:# There is no 5-part extension, so returned value is an empty stringsay "foo.tar.gz".IO.extension: :5parts; # OUTPUT: «»# There is no 5-part extension, so we replaced nothing:say "foo.tar.gz".IO.extension: 'ZIP', :5parts; # OUTPUT: «"foo.tar.gz".IO»# Replacing a 0-part extension is just appending:say "foo.tar.gz".IO.extension: 'ZIP', :0parts; # OUTPUT: «"foo.tar.gz.ZIP".IO»# Replace 1-part of the extension, using '.' joinersay "...".IO.extension: 'tar'; # OUTPUT: «"...tar".IO»# Replace 1-part of the extension, using empty string joinersay "...".IO.extension: 'tar', :joiner(''); # OUTPUT: «"..tar".IO»# Remove 1-part extension; results in empty basename, so result is ".".IOsay ".".IO.extension: ''; # OUTPUT: «".".IO»
方法 dirname§
method dirname(IO::Path:)
返回路径对象的目录名称部分。也就是说,它返回不包括 volume 和 base name 的路径。除非 dirname 仅 由目录分隔符组成(即它是顶级目录),否则返回的值中不会 包含尾随目录分隔符。
say IO::Path.new("/home/camelia/myfile.raku").dirname; # OUTPUT: «/home/camelia»say IO::Path::Win32.new("C:/home/camelia").dirname; # OUTPUT: «/home»say IO::Path.new("/home").dirname; # OUTPUT: «/»
方法 volume§
method volume(IO::Path:)
返回路径对象的卷部分。在 Unix 系统上,这始终为空字符串。
say IO::Path::Win32.new("C:\\Windows\\registry.ini").volume; # OUTPUT: «C:»
方法 parts§
method parts(IO::Path:)
为调用者返回一个 IO::Path::Parts
。
say IO::Path::Win32.new("C:/rakudo/raku.bat").parts.raku;# OUTPUT: «IO::Path::Parts.new("C:","/rakudo","raku.bat")»
注意:在 Rakudo 版本 2020.06 之前,返回一个 Map
,其键为 volume
、dirname
、basename
,其值分别为调用者的各个部分。
方法 raku§
method raku(IO::Path: --> Str)
返回一个字符串,当通过 EVAL
传递时,会返回原始调用者。
"foo/bar".IO.raku.say;# OUTPUT: IO::Path.new("foo/bar", :SPEC(IO::Spec::Unix), :CWD("/home/camelia"))
请注意,此字符串包括 .CWD
属性的值,该属性在默认情况下在创建路径对象时设置为 $*CWD
。
方法 gist§
method gist(IO::Path: --> Str)
返回一个字符串,其中一部分包含 .absolute
(如果路径是绝对路径)或 .path
的值。请注意,不会转义特殊字符,例如 "\b"
表示路径包含一个反斜杠和字母“b”,而不是退格符。
say "foo/bar".IO; # OUTPUT: «"foo/bar".IO»say IO::Path::Win32.new: 「C:\foo/bar\」; # OUTPUT: «"C:\foo/bar\".IO»
方法 Str§
method Str(IO::Path: --> Str)
IO::Path.path
的别名。特别地,请注意,IO::Path
的默认字符串化不会使用 $.CWD
属性 的值。要保留完整路径信息进行字符串化,请使用 .absolute
或 .relative
方法。
方法 succ§
method succ(IO::Path: --> IO::Path)
返回一个新的 IO::Path
,该 IO::Path
由调用者构建,其中 .basename
通过调用 Str.succ
进行更改。
"foo/file02.txt".IO.succ.say; # OUTPUT: «"foo/file03.txt".IO»
方法 open§
method open(IO::Path: *)
以文件形式打开路径;命名的选项控制模式,并且与 open 函数接受的选项相同。
方法 pred§
method pred(IO::Path: --> IO::Path)
返回一个新的 IO::Path
,该 IO::Path
由调用者构建,其中 .basename
通过调用 Str.pred
进行更改。
"foo/file02.txt".IO.pred.say; # OUTPUT: «"foo/file01.txt".IO»
方法 watch§
method watch(IO::Path: --> Supply)
等效于使用调用者作为参数调用 IO::Notification.watch-path。
方法 is-absolute§
method is-absolute(IO::Path: --> Bool)
如果路径是绝对路径,则返回 True
,否则返回 False
。
"/foo".IO.is-absolute.say; # OUTPUT: «True»"bars".IO.is-absolute.say; # OUTPUT: «False»
请注意,在 Windows 上,即使没有给出卷,以斜杠或反斜杠开头的路径仍被视为绝对路径,因为它对于该特定卷是绝对的。
IO::Path::Win32.new("/foo" ).is-absolute.say; # OUTPUT: «True»IO::Path::Win32.new("C:/foo").is-absolute.say; # OUTPUT: «True»IO::Path::Win32.new("C:foo" ).is-absolute.say; # OUTPUT: «False»
方法 is-relative§
method is-relative(IO::Path: --> Bool)
如果路径是相对路径,则返回 True
,否则返回 False
。适用于 .is-absolute
的 Windows 注意事项。
方法 absolute§
multi method absolute(IO::Path: --> Str)multi method absolute(IO::Path: --> Str)
返回一个新的 Str
对象,该对象是一个绝对路径。如果调用者还不是一个绝对路径,则首先使用 $base
作为基础使其成为绝对路径(如果提供了 $base
),或者使用创建对象时的 .CWD
属性(如果没有提供)。
方法 relative§
method relative(IO::Path: = --> Str)
返回一个新的 Str
对象,其路径相对于 $base
。如果未提供 $base
,则使用 $*CWD
代替。如果调用者不是绝对路径,则首先使用创建对象时的 .CWD
属性使其成为绝对路径,然后使其相对于 $base
。
方法 parent§
multi method parent(IO::Path:)multi method parent(IO::Path: UInt )
返回调用者的父路径。请注意,不会进行实际的文件系统访问,因此返回的父级是物理父级,而不是符号链接目录的逻辑父级。
'/etc/foo'.IO.parent.say; # OUTPUT: «"/etc".IO»'/etc/..' .IO.parent.say; # OUTPUT: «"/etc".IO»'/etc/../'.IO.parent.say; # OUTPUT: «"/etc".IO»'./' .IO.parent.say; # OUTPUT: «"..".IO»'foo' .IO.parent.say; # OUTPUT: «".".IO»'/' .IO.parent.say; # OUTPUT: «"/".IO»IO::Path::Win32.new('C:/').parent.say; # OUTPUT: «"C:/".IO»
如果指定了 $level
,则该调用等效于调用 .parent()
$level
次
say "/etc/foo".IO.parent(2) eqv "/etc/foo".IO.parent.parent; # OUTPUT: «True»
方法 resolve§
method resolve(IO::Path: : --> IO::Path)
返回一个新的 IO::Path
对象,其中所有符号链接和对父目录 (..
) 的引用都已解析。这意味着将检查路径中每个目录的文件系统,并遵循找到的任何符号链接。
# bar is a symlink pointing to "/baz"my = "foo/./bar/..".IO.resolve; # now "/" (the parent of "/baz")
如果将默认为 False
的 :$completely
设置为真值,则如果该方法无法完全解析路径,该方法将使用 X::IO::Resolve
fail
,否则,它将尽可能多地解析,并且只会对路径的其余部分执行 cleanup
。路径的最后一部分不必存在于 :$completely
中才能解析路径。
注意:目前(2017 年 4 月),此方法在所有平台上(例如 Windows)上都不能正常工作,因为 resolve
假设 POSIX 语义。
例程 dir§
multi dir(*)multi dir(IO::Path , |c)multi dir(IO() , |c)method dir(IO::Path: Mu : = .curupdir)
返回一个惰性列表,其中包含与目录中的条目对应的 IO::Path
对象,这些条目可以按 :test
参数对它们的名称作为字符串进行 智能匹配 进行可选筛选。文件系统返回条目的顺序决定了列表中条目/对象顺序。不包括对应于特殊目录条目 .
和 ..
的对象。$path
确定对象的路径是绝对路径还是相对路径。
由于测试是针对 Str
参数执行的,而不是 IO
,因此测试是在 $*CWD
中执行的,而不是在目标目录中。在针对文件测试运算符进行测试时,此方法将不起作用
dir('mydir', test => )
而这将起作用
dir('mydir', test => )
注意:dir
调用会打开一个目录以供读取,这会算入程序的最大每个进程打开文件数。务必在执行类似于递归执行更多 dir
调用的操作之前耗尽返回的 Seq
。你可以通过赋值给一个 @-
符号变量或简单地对其进行循环来耗尽它。请注意,以下示例将要进一步查看的目录推送到 Array
中,而不是立即对其调用 dir
。另请参阅 IO::Dir
模块,它可以让你更精细地控制关闭目录句柄。
示例
# To iterate over the contents of the current directory:for dir() -># As before, but include even '.' and '..' which are filtered out by# the default :test matcher:for dir(test => *) -># To get the names of all .jpg and .jpeg files in the home directory of the current user:my = .dir: test => /:i '.' jpe?g $/;
一个列出所有文件和目录(递归)的示例程序
sub MAIN( = '.')
一种从当前目录开始递归查找以 ".raku" 结尾的前三个文件的惰性方式
my = '.'.IO;my = gather while.put for [^3];
文件测试运算符§
对于大多数文件测试,你可以执行智能匹配 ~~
或调用一个方法。你不需要以传统方式实际打开一个文件句柄(尽管你可以这样做)来执行文件测试。你只需将 .IO
附加到文件名并将其智能匹配到一个测试副词。例如,以下是如何使用智能匹配检查文件是否可读
'/path/to/file'.IO ~~ :r;
文件测试包括
:d
(目录):e
(存在):f
(文件):l
(符号链接):r
(可读):rw
(可读且可写):rwx
(可读、可写且可执行):s
(大小):w
(可写):x
(可执行):z
(零大小)
这些测试不会缓存早期测试执行的结果。
对 Pair 进行智能匹配 可用于一次执行多个测试
say :d & :x; # OUTPUT: «all(d => True, x => True)»say '/tmp'.IO ~~ :d & :x; # OUTPUT: «True»say '/'.IO ~~ :d & :rw; # OUTPUT: «False»
以上所有测试都可以用作方法(不带冒号),尽管方法测试可能会抛出 X::IO::DoesNotExist
,如下所述。只有三个测试以方法形式存在:accessed
、changed
和 modified
。
你还可以通过针对文件句柄的 .path
方法进行测试,对已打开的文件句柄执行文件测试。例如,给定文件句柄 $fh
.path ~~ :r;.path.r; # method form
方法 e§
method e(IO::Path: --> Bool)
如果调用者是一个存在的路径,则返回 True
。
方法 d§
method d(IO::Path: --> Bool)
如果调用者是一个存在的路径且是一个目录,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
方法 f§
method f(IO::Path: --> Bool)
如果调用者是一个存在的文件路径,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
方法 s§
method s(IO::Path: --> Int)
返回文件大小(以字节为单位)。可以对目录路径进行调用,在这种情况下,报告的大小取决于操作系统。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
say .IO.s; # OUTPUT: «467»
方法 l§
method l(IO::Path: --> Bool)
如果调用者是一个存在且是符号链接的路径,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
方法 r§
method r(IO::Path: --> Bool)
如果调用者是一个存在且可访问的路径,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
方法 w§
method w(IO::Path: --> Bool)
如果调用者是一个存在且可写的路径,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
方法 rw§
method rw(IO::Path: --> Bool)
如果调用者是一个存在且可读写路径,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
方法 x§
method x(IO::Path: --> Bool)
如果调用者是一个存在且可执行的路径,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
注意:如果文件是一个脚本(一个可执行文本文件,而不是一个本机可执行文件),并且该文件只有可执行权限而没有读取权限,则此方法将返回 True
,但尝试执行将失败。这是操作系统的限制。
方法 rwx§
method rwx(IO::Path: --> Bool)
如果调用者是一个存在且可执行、可读写路径,则返回 True
。如果路径指向一个不存在的文件系统实体,则该方法将使用 X::IO::DoesNotExist
fail
。
方法 z§
method z(IO::Path: --> Bool)
如果调用者是一个存在且大小为 0
的路径,则返回 True
。可以对目录路径调用该方法,在这种情况下,报告的文件大小(以及该方法的结果)取决于操作系统。如果路径指向一个不存在的文件系统实体,该方法将使用 X::IO::DoesNotExist
fail
。
方法 sibling§
method sibling(IO::Path: Str() --> IO::Path)
允许引用同级文件或目录。返回一个基于调用者的新 IO::Path
,其中 .basename
更改为 $sibling
。$sibling
可以是一个多部分路径片段;另请参见 .add
。
say '.bashrc'.IO.sibling: '.bash_aliases'; # OUTPUT: «.bash_aliases".IO»say '/home/camelia/.bashrc'.IO.sibling: '.bash_aliases';# OUTPUT: «/home/camelia/.bash_aliases".IO»say '/foo/' .IO.sibling: 'bar'; # OUTPUT: «/bar".IO»say '/foo/.'.IO.sibling: 'bar'; # OUTPUT: «/foo/bar".IO»
方法 words§
method words(IO::Path: : = True, : = 'utf8', : = ["\x0A", "\r\n"], |c --> Seq)
打开调用者并返回其 words。
该行为等同于 打开 调用者指定的文件,将 :$chomp
、:$enc
和 :$nl-in
参数转发到 IO::Handle.open
,然后在该句柄上调用 IO::Handle.words
,将任何剩余参数转发到该方法,并返回结果 Seq
。
注意:单词是惰性读取的。在返回的 Seq
完全具体化 之前,底层使用的句柄不会关闭,这可能导致打开的文件句柄泄漏。可以使用 $limit
参数 避免打开的文件句柄泄漏,以减少要生成的单词 Seq
。
my := bag 'my-file.txt'.IO.words;say "Most common words: ", .sort(-*.value).head: 5;
方法 lines§
method lines(IO::Path: : = True, : = 'utf8', : = ["\x0A", "\r\n"], |c --> Seq)
打开调用者并返回其 lines。
该行为等同于 打开 调用者指定的文件,将 :$chomp
、:$enc
和 :$nl-in
参数转发到 IO::Handle.open
,然后在该句柄上调用 IO::Handle.lines
,将任何剩余参数转发到该方法,并返回结果 Seq
。
注意:行是惰性准备的,底层使用的句柄在返回的 Seq
完全具体化 之前不会关闭,因此请确保它具体化,否则会泄漏打开的文件句柄。(提示:使用 $limit
参数)
say "The file contains ",'50GB-file'.IO.lines.grep(*.contains: 'Raku').elems," lines that mention Raku";# OUTPUT: «The file contains 72 lines that mention Raku»
例程 slurp§
multi method slurp(IO::Path: :, :)
读取文件的所有内容,并将其作为 Buf
(如果 :$bin
为 True
)返回,如果不是,则作为使用 :$enc
编码(默认为 utf8
)解码的 Str
返回。之后将关闭文件。有关 :$enc
的有效值,请参见 &open
。
方法 spurt§
method spurt(IO::Path: , :, :, :)
打开路径以进行写入,并将所有 $data
写入其中。之后将关闭文件。如果由于任何原因无法成功,将 fail
。$data
可以是任何 Cool
类型或任何 Blob
类型。参数如下
:$enc
— 数据的字符编码。采用与IO::Handle.open
中:$enc
相同的值。默认为utf8
。如果$data
是Blob
,则忽略。:$append
— 以append
模式打开文件,保留现有内容,并将数据追加到文件末尾。:$createonly
— 如果文件已存在,则fail
。
method spurt(IO::Path:)
从 Rakudo 编译器的 2020.12 版本开始,还可以不带任何数据调用 spurt
方法。这将创建一个空文件,或截断给定路径处的任何现有文件。
方法 chdir§
multi method chdir(IO::Path: IO , |c)multi method chdir(IO::Path: Str() , : = True, :, :, :)
与名称相反,.chdir
方法不会更改任何目录,而只是将给定的 $path
与调用者连接,并返回结果 IO::Path
。可以通过提供 :d
、:r
、:w
或 :x
Bool
命名参数来执行可选的文件测试;当设置为 True
时,它们将分别执行 .d
、.r
、.w
和 .x
测试。默认情况下,只有 :d
设置为 True
。
方法 mkdir§
method mkdir(IO::Path: Int() = 0o777 --> IO::Path)
创建新目录,包括其父目录(类似于带有 -p
选项的 *nix 实用程序 mkdir
)。也就是说,如果 mkdir "foo/bar/ber/meow"
不存在,它还将创建 foo
、foo/bar
和 foo/bar/ber
目录。
如果成功,返回指向新创建目录的 IO::Path
对象;如果无法创建目录,则使用 X::IO::Mkdir
失败。
另请参阅 mode
以了解 $mode
的说明和有效值。
例程 rmdir§
sub rmdir(* --> List)method rmdir(IO::Path: --> True)
删除调用者,或在子表单中删除给定列表中提供的所有目录,该列表可以包含任何 Cool
对象。仅适用于空目录。
方法表单在成功时返回 True
,如果无法删除目录(例如,目录不为空或路径不是目录),则返回类型为 X::IO::Rmdir
的 Failure
。子例程表单返回成功删除的目录列表。
要删除非空目录,请参阅 File::Directory::Tree
模块中的 rmtree。
方法 chmod§
method chmod(IO::Path: Int() --> Bool)
将文件或目录的 POSIX 权限更改为 $mode
。成功时返回 True
;失败时,使用 X::IO::Chmod
失败。
模式应为遵循 标准数字表示法 的整数,最好写成八进制数
'myfile'.IO.chmod(0o444); # make a file read-only'somedir'.IO.chmod(0o777); # set 0777 permissions on a directory
确保您不会意外地将八进制数字作为十进制数(或包含十进制数的字符串)传递
'myfile'.IO.chmod: '0444'; # BAD!!! (interpreted as mode 0o674)'myfile'.IO.chmod: '0o444'; # OK (an octal in a string)'myfile'.IO.chmod: 0o444; # Also OK (an octal literal)
例程 rename§
method rename(IO::Path: IO() , : = False --> Bool)sub rename(IO() , IO() , : = False --> Bool)
重命名文件或目录。成功时返回 True
;如果 :$createonly
为 True
并且 $to
路径已存在或由于其他原因导致操作失败,则使用 X::IO::Rename
失败。
注意:某些重命名操作始终会失败,例如当新名称位于不同的存储设备上时。另请参阅:move
。
例程 copy§
method copy(IO::Path: IO() , : --> Bool)sub copy(IO() , IO() , : --> Bool)
复制文件。成功时返回 True
;如果 :$createonly
为 True
并且 $to
路径已存在或由于其他原因导致操作失败(例如当 $to
和 $from
是同一文件时),则使用 X::IO::Copy
失败。
例程 move§
method move(IO::Path: IO() , : --> Bool)sub move(IO() , IO() , : --> Bool)
复制文件,然后删除原始文件。如果删除失败,则可能最终得到该文件的两个副本。成功时返回 True
;如果 :$createonly
为 True
并且 $to
路径已存在或由于其他原因导致操作失败(例如当 $to
和 $from
是同一文件时),则使用 X::IO::Move
失败。
为避免复制,如果文件位于同一存储设备上,您可以使用 rename
。它还可以与目录一起使用,而 move
则不行。
方法 Numeric§
method Numeric(IO::Path: --> Numeric)
将 .basename
强制转换为 Numeric
。如果基本名称不是数字,则使用 X::Str::Numeric
失败。
方法 Int§
method Int(IO::Path: --> Int)
将 .basename
强制转换为 Int
。如果基本名称不是数字,则使用 X::Str::Numeric
失败。
例程 symlink§
method symlink(IO::Path : IO() , Bool : = True --> Bool)sub symlink( IO() , IO() , Bool : = True --> Bool)
为现有的 $target
创建新的符号链接 $link
。成功时返回 True
;如果无法创建符号链接,则使用 X::IO::Symlink
失败。如果 $target
不存在,则创建一个悬空符号链接。
symlink
默认使用绝对路径创建符号链接。要创建相对符号链接,请将 absolute
参数设置为 False
,例如 :!absolute
。此标志在 Rakudo 版本 2020.11 中引入。
要创建硬链接,请参阅 link
。
注意:在 Windows 上,创建符号链接可能需要提升的权限。
routine link§
method link(IO::Path : IO() --> Bool)sub link( IO() , IO() --> Bool)
为现有的 $target
创建一个新的硬链接 $link
。如果成功,则返回 True
;如果无法创建硬链接,则使用 X::IO::Link
失败。要创建符号链接,请参阅 symlink
。
routine unlink§
method unlink(IO::Path: --> True)sub unlink(* --> List)
删除所有指定的文件、链接或符号链接,并具有执行此操作的权限。请参阅 rmdir 以删除目录。
子例程形式返回列表中所有文件的名称,不包括文件系统引发错误的文件;由于尝试删除不存在的文件不会在该级别引发任何错误,因此此列表将包括列表中不存在的文件的名称。
方法形式在成功时返回 True
,或者如果无法完成操作,则使用 X::IO::Unlink
失败。如果要删除的文件不存在,则例程将其视为成功。
'foo.txt'.IO.open(:w).close;'bar'.IO.mkdir;say unlink <foo.txt bar not-there.txt>; # OUTPUT: «[foo.txt not-there.txt]»# `bar` is not in output because it failed to delete (it's a directory)# `not-there.txt` is present. It never existed, so that's deemed a success.# Method form `fail`s:say .exception.message without 'bar'.IO.unlink;# OUTPUT: «Failed to remove the file […] illegal operation on a directory»
routine chown§
method chown(IO::Path: :, : --> True)sub chown(*, :, : --> List)
在 Rakudo 编译器的 2022.12 版本中可用。
更改所有指定的文件、链接或符号链接的所有者和/或组,并具有执行此操作的权限。
子例程形式返回列表中所有文件的名称,不包括文件系统引发错误的文件。
方法形式在成功时返回 True
,或者如果无法完成操作,则使用 X::IO::Chown
失败。
请注意,此操作仅适用于具有“所有者”和“组”概念的操作系统,这通常在类 Unix 系统上。
say "success" if 'foo.txt'.IO.chown(:uid(137));
method IO§
method IO(IO::Path: --> IO::Path)
返回调用者。
method SPEC§
method SPEC(IO::Path: --> IO::Spec)
返回在对象创建时(隐式)指定的 IO::Spec
对象。
my = IO::Path.new("/bin/bash");say .SPEC; # OUTPUT: «(Unix)»say .SPEC.dir-sep; # OUTPUT: «/»
文件时间戳检索§
还有 3 种方法用于获取文件(inode)的 3 个时间戳,在这些时间戳可用的操作系统上
method created§
返回一个 Instant
对象,指示文件创建的时间。
say "path/to/file".IO.created; # Instant:1424089165say "path/to/file".IO.created.DateTime; # 2015-02-16T12:18:50Z
在 Rakudo 编译器的 2022.12 版本中可用。
method modified§
返回一个 Instant
对象,指示文件内容上次修改的时间。与 changed 进行比较。
say "path/to/file".IO.modified; # Instant:1424089165say "path/to/file".IO.modified.DateTime; # 2015-02-16T12:18:50Z
方法 accessed§
返回一个表示文件上次访问时间戳的 Instant
对象。注意:根据文件系统挂载方式,上次访问时间可能不会在每次访问文件时更新,而只在修改后首次访问时更新。
say "path/to/file".IO.accessed; # Instant:1424353577say "path/to/file".IO.accessed.DateTime; # 2015-02-19T13:45:42Z
方法 changed§
返回一个 Instant
对象,表示文件或目录的元数据上次更改的时间(例如,权限或目录中创建/删除的文件)。与 modified 进行比较。
say "path/to/file".IO.changed; # Instant:1424089165say "path/to/file".IO.changed.DateTime; # 2015-02-16T12:18:50Z
文件权限检索§
方法 mode§
返回一个表示文件的 POSIX 权限的 IntStr
对象。结果的 Str
部分是文件权限的八进制表示,类似于 chmod(1)
实用程序接受的形式。
say ~"path/to/file".IO.mode; # e.g. '0644'say +"path/to/file".IO.mode; # e.g. 420, where sprintf('%04o', 420) eq '0644'
此结果可用于将模式作为参数的其他方法中。
"path/to/file1".IO.chmod("path/to/file2".IO.mode); # will change the# permissions of file1# to be the same as file2
其他信息方法§
方法 user§
在 2021.04 Rakudo 编译器版本中可用。
user
方法返回支持此类概念的操作系统上的路径的数字用户 ID(又称“uid”)。
方法 group§
在 2021.04 Rakudo 编译器版本中可用。
group
方法返回支持此类概念的操作系统上的路径的数字组 ID(又称“gid”)。
方法 dir-with-entries§
在 2022.04 Rakudo 编译器版本中可用。
返回一个 Bool
,表示路径是否是其中包含任何条目的目录。如果路径不是目录或路径不存在,则抛出异常。
say "'$_' has entries" if .d && .dir-with-entries given "path/to/dir".IO;
方法 inode§
在 2022.07 Rakudo 编译器版本中可用。
返回一个 Int
对象,表示文件系统上路径的 inode(如果文件系统支持此类概念)。
say "path/to/file".IO.inode; # e.g. 9003678
方法 dev§
在 2022.07 Rakudo 编译器版本中可用。
返回一个 Int
对象,表示文件系统上路径的 dev
(POSIX stat
函数的 st_dev
字段)(如果文件系统支持此类概念)。
say "path/to/file".IO.dev; # e.g. 16777233
方法 devtype§
在 2022.07 Rakudo 编译器版本中可用。
返回一个 Int
对象,表示文件系统中路径的 devtype
(POSIX stat
函数的 st_rdev
字段)(如果文件系统支持此类概念)。
say "path/to/file".IO.devtype; # e.g. 0