跳转到内容

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;

写入文件

[编辑 | 编辑源代码]

关闭文件

[编辑 | 编辑源代码]
  1. 泛化为IO 句柄,用于与其他 IO 对象(如流、套接字等)进行交互。

外部资源

[编辑 | 编辑源代码]
华夏公益教科书