Raku Programming/Files
Before we begin
[edit | edit source]Filehandle
[edit | edit source]Any interaction with files in Raku happens through a filehandle. [note 1] A filehandle is an internal name for an external file. The open
function makes the association between the internal name and the external name, while the close
function breaks that association. Some IO handles are available for your use without the need to create them: $*OUT
and $*IN
are connected to STDOUT and STDIN, the standard output and standard input streams, respectively. You will need to open every other filehandle on your own.
Paths
[edit | edit source]Always remember, that any path to a file within the program is with respect to the current working directory.
File operations: Text
[edit | edit source]Open a file for reading
[edit | edit source]To open a file, we need to create a filehandle to it. This simply means that we create a (scalar) variable which will refer to the file from now on. The two argument syntax is the most common way to call the open
function: open PATHNAME, MODE
—where PATHNAME
is the external name of the file you want opened and MODE
is the type of access. If successful, this returns an IO handle object which we can put into a scalar container:
my $filename = "path/to/data.txt";
my $fh = open $filename, :r;
The :r
opens the file in read-only mode. For brevity, you can omit the :r
—since it is the default mode; and, of course, the PATHNAME
string can be passed directly, instead of passing it via a $filename
variable.
Once we have a filehandle, we can read and perform other actions on the file.
New Way
[edit | edit source]Use slurp and spurt instead, as:
"file.txt".IO.spurt: "file contents here";
"file.txt".IO.slurp.say; # «file contents here»
Read an opened file
[edit | edit source]The most general approach to file reading avails itself with the establishment of a connection to the resource via the open
function, followed by the data consumption step, and terminating with an invocation of close
on the file handle received during the opening procedure.
my $fileName;
my $fileHandle;
$fileName = "path/to/data.txt";
$fileHandle = open $fileName, :r;
# Read the file contents by the desiderated means.
$fileHandle.close;
To transfer the file data immediately and completely into the program, the slurp
function can be used. Commonly, this involves the obtained string's storage into a variable for further manipulations.
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;
If a complete data consumption is, either because of a line-oriented programming task or memory considerations, undesirable, a line by line reading can be accomplished through the IO.lines
function.
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;
A file handle's employment enables the resource's reuse, but on the other hand obliges the programmer to attend its management. If the offered advantages do not merit these expenses, the functions mentioned above can work directly upon a file name represented by its string.
The complete file contents can be read by specifying the file name as a string and invoking the IO.slurp
upon it.
my $fileName;
my $fileContents;
$fileName = "path/to/data.txt";
$fileContents = $fileName.IO.slurp;
If this object-oriented approach does not befit one's style, the equivalent procedural variant is:
my $fileName;
my $fileContents;
$fileName = "path/to/data.txt";
$fileContents = slurp $fileName;
In the same mode, a file handle free processing on a line-by-line basis comprises:
my $fileName;
my $fileContents;
$fileName = "path/to/data.txt";
for $fileName.IO.lines -> $line {
# Utilize the "$currentLine" variable, which holds a string.
}
Remember the option to insert the file name without storage in a variable, which curtails the above code passages even more. Transferring the complete file contents, in corollary, might be reduced to:
my $fileContents = "path/to/data.txt".IO.slurp;
or
my $fileContents = slurp "path/to/data.txt";
In order to access a file on a finer level of granularity, Raku of course provides facilities for a specified amount of characters' retrieval through the readchars
function, which accepts the tally of characters to consume and returns a string representing the obtained data.
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;
Write to a file
[edit | edit source]Close a file
[edit | edit source]Notes
[edit | edit source]- ↑ generalized to IO handles for interaction with other IO objects like streams, sockets, etc.