Skip to content
Kavachकवच

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 errors
lines.kav: Kavach code, then what running it prints
  • fs.lines keeps only the line being looked at in memory, so a file of many gigabytes is fine.
  • Lines come without their ending, \n or \r\n.
  • A read that fails halfway goes to the try in 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
bytes.kav: Kavach code, then what running it prints

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?.