retroforth/doc/book/techniques/files

166 lines
4.1 KiB
Text
Raw Normal View History

# Working With Files
On Unix and Windows systems RETRO provides a set of words for
working with files. As a pragmatic choice these are mostly
modeled after the file functions in libc.
The file words are in the `file:` namespace.
## File Access Modes
You can open a file for various operations. The functionality
allowed depends on the file access mode. Valid modes in RETRO
are:
file:A Open for appending; file pointer set to end of file
file:R Open for reading; file pointer set to start of file
file:R+ Open for reading and writing
file:W Open for writing
## Opening A File
To open a file, pass the file name and a file mode to `file:open`.
'/etc/motd file:R file:open
On a successful open this will return a file handle greater than
zero.
Additionally, RETRO provides a few other forms for opening files.
To open a file for reading:
'/etc/motd file:open<for-reading>
This will return the size of the file (as NOS) and the file handle
(as TOS).
To open a file for writing:
'/tmp/test file:open<for-writing>
This returns the file handle.
To open a file for append operations:
'/tmp/test file:open<for-append>
As with `file:open<for-reading>`, this returns both the size of
the file and the file handle.
## Closing A File
To close a file, pass the file handle to `file:close`.
'/etc/motd file:A file:open file:close
## Reading From A File
To read a byte from an open file, pass the file handle to the
`file:read` word.
@FID file:read n:put
To read a line from a file, pass the file handle to the word
`file:read-line`.
@FID file:read-line s:put
The line is read into a temporary string buffer. Move the
text to a safe place if you aren't using it quickly or if
the length of the line is bigger than the size of a temporary
string.
## Writing To A File
To write a byte to a file, pass it and the file handle to
`file:write`.
$h @FID file:write
$e @FID file:write
$l @FID file:write
$l @FID file:write
$o @FID file:write
Though cells are 32 or 64 bits in size, only the byte value will
be written to the file.
## Deleting Files
You can delete a file by passing the file name to `file:delete`.
/tmp/test file:delete
## Check For File Existance
Use `file:exists?` to detect the existance of a file. Pass it a
file name and it will return `TRUE` if existing or `FALSE` if
it does not.
'/etc/motd file:exists?
This will also return `TRUE` if the filename is a directory.
## Flush Caches
Use `file:flush` to flush the system caches for a file. Pass a
file handle to this.
@FID file:flush
## Seek A Position Within A File
You can use `file:seek` to move the internal file pointer
for a given file. Pass this the new location and a file.
#100 @FID file:seek
The location for the file pointer is a fixed offset from the
start of the file, not a relative offset.
## Get The Current Position Within A File
To find the current value of the file pointer within a file
just pass the file handle to `file:tell`.
@FID file:tell
This returns a number that is the number of bytes into the file
that the file pointer is currently at.
## Determine The Size Of A File
Use `file:size` to return the size of a file. Pass this a file
handle and it will return the size of a file, or 0 if empty. If
the file is a directory, it returns -1.
@FID file:size
## Reading An Entire File
If you want to read an entire file into memory you can use
`file:slurp`. This takes the starting address of a memory
region and the name of the file.
here '/etc/motd file:slurp
Take care that the memory buffer is large enough for the file
being read or you will run into problems.
## Writing A String To A File
If you have a string that you want to write to a file, replacing
any existing contents, you can use `file:spew`. This takes the
string to write and a file name.
'hello_world '/tmp/test.txt file:spew
## Iterating Over A File, Line By Line
You can easily iterate over each line in a file using the word
`file:for-each-line`. This will take a file name and a quote,
read each line into a temporary string, then pass this string to
the quote.
'/etc/motd [ s:put nl ] file:for-each-line