Hello, everyone.
In this sequence we'll look at the API for manipulating files.
What we'll be looking at particularly
is how to navigate between files,
how to create and remove files,
how to list files in the directories,
and how to read from and write to files.
To begin with,
we need an entry point in the file system,
there are many.
With "FileLocator home" you have the user directory,
"FileLocator root" you have the root
of the directory system.
With "FileLocatorC" in Windows you have disc C:
Once you have a directory,
these 3 elements are directories,
I take one, "FileLocator home"
in which I have the user home directory.
From there I can say,
"Give me your access path".
So "home" isn't a string, it's an object that represents
a directory and I can say,
"Give me the string locating you in the system".
So that's "home/cassou".
I can ask a directory where its children are.
"What are all the files and directories you contain?"
Here it tells me, in "home".
I've a file named .bashrc,
and I've a Music directory.
So this, "children",
returns a bundle of objects,
which are files and directories.
If we play a bit more with this API,
we'll see the method "/",
When we send the message /
to a directory we can indicate a particular child that interests us.
So "home/'Music'" gives me the Music directory.
By sending the message "directories" to a file,
I get all the sub files.
Here I see that, in my Music library,
I have a file Anouar_Brahem.
The parent message allows me to go up a rung,
so if I'm in the Music file,
I send "parent" but I return to my "home" file.
Leaving my directory
"Music", as we saw before, I'll try to create a directory.
To do this, I check if the directory exists.
By sending a message "isDirectory"
I see whether it exists or not.
This says it doesn't exist.
All right, I create it with "ensureCreateDirectory".
Then I test it, "do you exist?" In this case it exists,
with "delete" I can erase it, and I check it's deleted
by sending ""isDirectory".
To find
all the children in a directory,
there are several methods. I'll show you two.
We send a message, "allChildrenMatching" to a directory,
and by passing it an expression
that's typical of the ladder and which represents
the name of the directory we expect, so with "*.org",
I want all the files to have the extension ".ogg".
That will return all my music files to .ogg in my Pink Floyd directory.
I can do the same thing in a more long-winded way.
By sending the message "allChildren" I get all the children
all the files and directories, in a particular directory,
and I filter with the message "select"
all those whose name ends in ".ogg".
"Basename" returns the string representing the file name
and I want the file name to end in .ogg.
These two bits of code are almost the same.
How do we get information about a file?
How do we create a file from a string?
I've a file name, "asFileReference",
which turns my file name into a reference towards a file.
It can be an existing or a non-existent file, I don't know.
Let's look at the message "isFile" at this reference.
I'll get "true" if it exists and "false" if it doesn't.
By sending the message "basename", I get the name of the file.
By sending "extension" I get the file extension,
with "size" I get the size,
and with "PathString", as we saw before,
I get the access path in the form of a string.
Now let's see how to write to and read from a file. To write,
first of all, I take a reference towards a file.
Here, I check that it doesn't exist.
We can write to a file that exists, I'm checking it doesn't exist.
I write to it. To write, I create a stream.
With "nextPutAll"
I ask to write each character of the stream to the file.
At the end I close my stream to ensure that the system
has written everything to the disc.
Conversely, I can read
from a file, so I take the same file and .txt.
I check it exists, and it does, because I can write to it.
I create a "ReadStream"
and I look, either character by character by sending "next".
With the message "next" I'll get, "h" then "e" then "l", etc...
I do "next" once, I get "h".
Afterwards I'll pick up everything,
from the first "h" I've just read to the end of the file.
Here I get "ello World" without the "h".
At the end, I send "stream close" to the stream object,
to ensure the file reference is closed.
We can write these codes more simply,
without having the need
to send the "close" message.
We might forget to send the "close" message.
There can be an exception that means "close" is never sent.
In general, we try to avoid having to write it ourselves.
To do this, to write,
I take my file reference,
I send the message "writeStreamDo",
which takes a block in parentheses,
the block takes one stream in parentheses.
This stream will be automatically provided by "writeStreamDo"
which will create a "writeStream" on the file.
The only thing I need to do is, by using this stream,
manipulate the stream to do what I want with the file.
I'll write "Hello World" to the file, "stream nextPutAll: Hello World".
When the block finishes,
the stream closes automatically, and the file writes to the disc.
Same principle for reading, I put "readStreamDo".
Here I have a stream, I can do what I want with it.
I decide to retrieve the contents of the stream.
What you should know,
is that files and directories are references,
they're references towards files and directories on the disc
that may or may not exist. Check with "isFile", "isDirectory"
if the files exist on the disc.
The API is simple,
and facilitates navigation and manipulation of the files.
We can read from and write to files through streams,
and with an API
which will close the stream automatically at the end.