[0.15.2] Reading a file line by line

Hi, I know this question has kind of been asked before here, but the answer is old now and it does not apply to the latest version of zig anymore, so I was wondering how to use the new Reader interface from calling file.reader(buffer); plus I would like to understand what is buffer doing and if this is the preferred way of doing this or is there other alternative.

You want something like this:

    var read_buffer: [1024]u8 = undefined;
    var reader = file.reader(&read_buffer);

    while (true) {
        const line = reader.interface.takeDelimiterInclusive('\n') catch |err| switch (err) {
            error.EndOfStream => break,
            error.ReadFailed => |e| return reader.err orelse e,
            else => |e| return e,
        };
        std.log.info("Read: {s}", .{line});
    }

The buffer needs to be as large as the longest line you expect in the file. It’s used to accumulate data until the reader reaches the expected character, newline in this case.

2 Likes

You can mark a reply as the solution


some things to be aware of:

The new Reader/Writer interfaces don’t contain a pointer to the implementation. As a result, if an implementation has state it needs to access, it does some pointer arithmetic under the assumption that the interface pointer it gets is a pointer to a field of its state type.

Just be aware of that so you don’t break that assumption, or if you do get weird results, you know what to check first.

This kind of interface is called an ‘intrusive interface’, there are pros and cons.


You can provide a zero length buffer to disable buffering, e.g. &.{}(my preference), "" or &[0/_]u8{}. Writers with a non zero buffer size should have flush called at whatever point you need to ensure all data is written.

Some APIs may have requirements around the buffer size, for example all the peek* and take* functions on Reader require at least a non-zero buffer length.

You should also, where applicable, have your own buffer requirements to simplify your own code.

Also think about the maximum data you need at a time when considering buffer size.

If you’re not sure, just pick a number, probably something on the order of kilo/megabytes. But ofc consider your use case.