LessonsAdvanced: Bigger programsLesson 42

Files a piece at a time

Open a file and read or write it a line or a block at a time, for files too big to read whole, and for logs you add to as you go.

  • Advanced
  • Lesson 42 of 83
  • About 9 minutes
  • 6 examples

When a URL is not enough

URL "file:" reads or writes a whole file at once, which is right for almost every file. But a log of millions of lines does not need to be in memory to read its last entry, and a program that writes as it goes should not rewrite the whole file each time. For these, open the file and work on it a piece at a time:

  1. open file it, for read, for write (replacing it), for append (adding to the end) or for update;
  2. read from file or write to file, as often as you need;
  3. close file it, always.

Writing a line at a time

ExampleRun it in the playground
put specialFolderPath("temporary") & "/oxt-lesson-stream.txt" into tPath
open file tPath for write
repeat with i = 1 to 3
   write "line" && i & return to file tPath
end repeat
close file tPath
put the number of lines of URL ("file:" & tPath)
delete file tPath
Output
3

Reading a line at a time

read from file puts what it read in it. Read for 1 line, or until return, and loop until there is nothing left:

ExampleRun it in the playground
put specialFolderPath("temporary") & "/oxt-lesson-stream.txt" into tPath
put "alpha" & return & "beta" & return & "gamma" & return into URL ("file:" & tPath)
open file tPath for read
repeat
   read from file tPath for 1 line
   if it is empty then exit repeat
   put "got:" && line 1 of it
end repeat
close file tPath
delete file tPath
Output
got: alpha
got: beta
got: gamma

What was read includes the return at the end of the line, which is why the example takes line 1 of it.

Reading from a position

A file is read from where the last read stopped. You can also read from any position with at, a number of characters with for, or everything left until EOF (the end of the file):

ExampleRun it in the playground
put specialFolderPath("temporary") & "/oxt-lesson-digits.txt" into tPath
put "0123456789" into URL ("file:" & tPath)
open file tPath for read
read from file tPath at 4 for 3
put it
read from file tPath until EOF
put it
close file tPath
delete file tPath
Output
345
6789

Positions count from 1, as everywhere in xTalk. For a binary file, open it for binary read and positions count bytes.

Adding to a log

for append writes after whatever the file holds already, which is just what a log needs:

ExampleRun it in the playground
put specialFolderPath("temporary") & "/oxt-lesson-app.log" into tPath
put "started" & return into URL ("file:" & tPath)

command logLine pPath, pText
   open file pPath for append
   write pText & return to file pPath
   close file pPath
end logLine

logLine tPath, "loaded 3 files"
logLine tPath, "finished"
put URL ("file:" & tPath) into tLog
put the number of lines of tLog
put line -1 of tLog
delete file tPath
Output
3
finished

Always close

An open file stays open, and on some systems locked, until you close it or the program quits. the openFiles lists the files still open. Close every file you open, even when something goes wrong: a try with finally (from Handling errors) makes sure of it.

ExampleRun it in the playground
put specialFolderPath("temporary") & "/oxt-lesson-safe.txt" into tPath
put "data" into URL ("file:" & tPath)
try
   open file tPath for read
   read from file tPath until EOF
   put "read:" && it
   throw "something went wrong while working"
catch tError
   put "error:" && tError
finally
   close file tPath
end try
put "files still open:" && the number of lines of the openFiles
delete file tPath
Output
read: data
error: something went wrong while working
files still open: 0

Try it yourself

Write the numbers 1 to 1000 to a file, a line each, with write. Then read the file a line at a time and add up only the lines that are multiples of 7. Put the total, and delete the file.

Show a solution
ExampleRun it in the playground
put specialFolderPath("temporary") & "/oxt-lesson-numbers.txt" into tPath
open file tPath for write
repeat with i = 1 to 1000
   write i & return to file tPath
end repeat
close file tPath
put 0 into tTotal
open file tPath for read
repeat
   read from file tPath for 1 line
   if it is empty then exit repeat
   put line 1 of it into tNumber
   if tNumber mod 7 is 0 then add tNumber to tTotal
end repeat
close file tPath
delete file tPath
put tTotal
Output
71071

Words in this lesson

Each one finds every lesson that uses it. The Dictionary has the whole story of each, with its syntax and more examples.