1# Working With Files
2
3On Unix and Windows systems RETRO provides a set of words for
4working with files. As a pragmatic choice these are mostly
5modeled after the file functions in libc.
6
7The file words are in the `file:` namespace.
8
9## File Access Modes
10
11You can open a file for various operations. The functionality
12allowed depends on the file access mode. Valid modes in RETRO
13are:
14
15    file:A    Open for appending; file pointer set to end of file
16    file:R    Open for reading; file pointer set to start of file
17    file:R+   Open for reading and writing
18    file:W    Open for writing
19
20## Opening A File
21
22To open a file, pass the file name and a file mode to `file:open`.
23
24    '/etc/motd file:R file:open
25
26On a successful open this will return a file handle greater than
27zero.
28
29Additionally, RETRO provides a few other forms for opening files.
30
31To open a file for reading:
32
33    '/etc/motd file:open-for-reading
34
35This will return the size of the file (as NOS) and the file handle
36(as TOS).
37
38To open a file for writing:
39
40    '/tmp/test file:open-for-writing
41
42This returns the file handle.
43
44To open a file for append operations:
45
46    '/tmp/test file:open-for-append
47
48As with `file:open-for-reading`, this returns both the size of
49the file and the file handle.
50
51## Closing A File
52
53To close a file, pass the file handle to `file:close`.
54
55    '/etc/motd file:A file:open file:close
56
57## Reading From A File
58
59To read a byte from an open file, pass the file handle to the
60`file:read` word.
61
62    @FID file:read n:put
63
64To read a line from a file, pass the file handle to the word
65`file:read-line`.
66
67    @FID file:read-line s:put
68
69The line is read into a temporary string buffer. Move the
70text to a safe place if you aren't using it quickly or if
71the length of the line is bigger than the size of a temporary
72string.
73
74## Writing To A File
75
76To write a byte to a file, pass it and the file handle to
77`file:write`.
78
79    $h @FID file:write
80    $e @FID file:write
81    $l @FID file:write
82    $l @FID file:write
83    $o @FID file:write
84
85Though cells are 32 or 64 bits in size, only the byte value will
86be written to the file.
87
88## Deleting Files
89
90You can delete a file by passing the file name to `file:delete`.
91
92    /tmp/test file:delete
93
94## Check For File Existance
95
96Use `file:exists?` to detect the existance of a file. Pass it a
97file name and it will return `TRUE` if existing or `FALSE` if
98it does not.
99
100    '/etc/motd file:exists?
101
102This will also return `TRUE` if the filename is a directory.
103
104## Flush Caches
105
106Use `file:flush` to flush the system caches for a file. Pass a
107file handle to this.
108
109    @FID file:flush
110
111## Seek A Position Within A File
112
113You can use `file:seek` to move the internal file pointer
114for a given file. Pass this the new location and a file.
115
116    #100 @FID file:seek
117
118The location for the file pointer is a fixed offset from the
119start of the file, not a relative offset.
120
121## Get The Current Position Within A File
122
123To find the current value of the file pointer within a file
124just pass the file handle to `file:tell`.
125
126    @FID file:tell
127
128This returns a number that is the number of bytes into the file
129that the file pointer is currently at.
130
131## Determine The Size Of A File
132
133Use `file:size` to return the size of a file. Pass this a file
134handle and it will return the size of a file, or 0 if empty. If
135the file is a directory, it returns -1.
136
137    @FID file:size
138
139## Reading An Entire File
140
141If you want to read an entire file into memory you can use
142`file:slurp`. This takes the starting address of a memory
143region and the name of the file.
144
145    here '/etc/motd file:slurp
146
147Take care that the memory buffer is large enough for the file
148being read or you will run into problems.
149
150## Writing A String To A File
151
152If you have a string that you want to write to a file, replacing
153any existing contents, you can use `file:spew`. This takes the
154string to write and a file name.
155
156    'hello_world '/tmp/test.txt file:spew
157
158## Iterating Over A File, Line By Line
159
160You can easily iterate over each line in a file using the word
161`file:for-each-line`. This will take a file name and a quote,
162read each line into a temporary string, then pass this string to
163the quote.
164
165    '/etc/motd [ s:put nl ] file:for-each-line
166