Files: Reading
● Intermediate4 min
fs.read_text reads a whole file; fs.lines reads it one line at a time, for files of any size.
use std.fs
fn main() ! Error {
try fs.write_text("server.log", "INFO start\nERROR disk full\nINFO retry\nERROR disk full\n")
let errors = 0
for line in try fs.lines("server.log") {
if line.contains("ERROR") {
errors += 1
}
}
print("{errors} errors")
}The program ran and printed:
kavach run lines.kav
2 errorsfs.lineskeeps only the line being looked at in memory, so a file of many gigabytes is fine.- Lines come without their ending,
\nor\r\n. - A read that fails halfway goes to the
tryin the loop's header, so half a file is never taken for a whole one.
Files that aren't text are read as Bytes, whole or in pieces:
use std.fs
fn main() ! Error {
try fs.write_bytes("logo.bin", "GIF89a".bytes())
const data = try fs.read_bytes("logo.bin")
print(data.len())
for chunk in try fs.chunks("logo.bin", 4) {
print(chunk.len())
}
}The program ran and printed:
kavach run bytes.kav
642
Big pieces are read ahead
fs.chunks keeps only the piece being looked at in memory. With pieces of 1 MB or more, the next piece is in memory too: a native program reads it on a helper thread while the loop works on this one, so the disk and the work overlap. There is nothing to write. The interpreter, plain kavach run, doesn't do this.
- The file's bytes and the order of the pieces stay the same, and an error comes at the same point of the loop.
- A change the program makes to the file during the loop may not show in the piece after.
What it gains is measured on Can I use it on the GPU?.