Raku 编程/文件
在 Raku 中,任何与文件交互都通过文件句柄进行。[注释 1] 文件句柄是外部文件的内部名称。open
函数建立了内部名称和外部名称之间的关联,而 close
函数则打破这种关联。某些 IO 句柄无需创建即可使用:$*OUT
和 $*IN
分别连接到 STDOUT 和 STDIN,即标准输出流和标准输入流。您需要自己打开其他所有文件句柄。
始终记住,程序中任何指向文件的路径都相对于当前工作目录。
要打开文件,我们需要为其创建一个文件句柄。这仅仅意味着我们创建一个(标量)变量,它将从现在开始引用该文件。使用两个参数的语法是调用 open
函数的最常见方式:open PATHNAME, MODE
- 其中 PATHNAME
是您要打开的文件的外部名称,而 MODE
是访问类型。如果成功,这将返回一个 IO 句柄对象,我们可以将其放入标量容器中
my $filename = "path/to/data.txt";
my $fh = open $filename, :r;
:r
以只读模式打开文件。为简洁起见,您可以省略 :r
- 因为它是默认模式;并且,当然,可以将 PATHNAME
字符串直接传递,而不是通过 $filename
变量传递。
一旦我们有了文件句柄,我们就可以读取文件并对文件执行其他操作。
改用 slurp 和 spurt,因为
"file.txt".IO.spurt: "file contents here";
"file.txt".IO.slurp.say; # «file contents here»
最通用的文件读取方法是通过 open
函数建立与资源的连接,然后执行数据消费步骤,最后在打开过程中接收到的文件句柄上调用 close
。
my $fileName;
my $fileHandle;
$fileName = "path/to/data.txt";
$fileHandle = open $fileName, :r;
# Read the file contents by the desiderated means.
$fileHandle.close;
要将文件数据立即完全传输到程序中,可以使用 slurp
函数。通常,这包括将获取的字符串存储到变量中以进行进一步操作。
my $fileName;
my $fileHandle;
my $fileContents;
$fileName = "path/to/data.txt";
$fileHandle = open $fileName, :r;
# Read the complete file contents into a string.
$fileContents = $fileHandle.slurp;
$fileHandle.close;
如果由于面向行的编程任务或内存考虑而无法完全消耗数据,则可以通过 IO.lines
函数逐行读取数据。
my $fileName;
my $fileHandle;
$fileName = "path/to/data.txt";
$fileHandle = open $fileName, :r;
# Iterate the file line by line, each line stored in "$currentLine".
for $fileHandle.IO.lines -> $currentLine {
# Utilize the "$currentLine" variable which holds a string.
}
$fileHandle.close;
文件句柄的使用可以重复利用资源,但另一方面,它也要求程序员注意其管理。如果提供的优势不值得这些开销,则上述函数可以直接作用于用字符串表示的文件名。
可以通过指定文件名作为字符串并对其调用 IO.slurp
来读取完整的文件内容。
my $fileName;
my $fileContents;
$fileName = "path/to/data.txt";
$fileContents = $fileName.IO.slurp;
如果这种面向对象的方案不符合您的风格,则等效的程序性变体是
my $fileName;
my $fileContents;
$fileName = "path/to/data.txt";
$fileContents = slurp $fileName;
在相同模式下,文件句柄的自由逐行处理包括
my $fileName;
my $fileContents;
$fileName = "path/to/data.txt";
for $fileName.IO.lines -> $line {
# Utilize the "$currentLine" variable, which holds a string.
}
请记住,可以选择在不将文件名存储到变量的情况下插入文件名,这会进一步缩短上述代码段。相应地,传输完整的文件内容可能会简化为
my $fileContents = "path/to/data.txt".IO.slurp;
或
my $fileContents = slurp "path/to/data.txt";
为了以更细的粒度访问文件,Raku 当然提供了通过 readchars
函数检索指定数量字符的功能,该函数接受要消耗的字符数并返回表示获取数据的字符串。
my $fileName;
my $fileHandle;
my $charactersFromFile;
$fileName = "path/to/data.txt";
$fileHandle = open $fileName, :r;
# Read eight characters from the file into a string variable.
$charactersFromFile = $fileHandle.readchars(8);
# Perform some action with the "$charactersFromFile" variable.
$fileHandle.close;
- ↑ 泛化为IO 句柄,用于与其他 IO 对象(如流、套接字等)进行交互。