manu

July 18, 2026, 4:08pm 1

I am playing around with Zig, so I thought to create a basic program that reads from a file (or stdio) and writes to a file (or stdout). But I was getting pretty confused with Io, File, Reader and Writer. And I am still unsure about a few things.

I now have this for writing to stdout:

    const io = init.io;
    var stdout_buffer: [1024]u8 = undefined;
    var stdout_writer = std.Io.File.stdout().writer(io, &stdout_buffer);
    const stdout = &stdout_writer.interface;
    try stdout.print("Hello world\n", .{});
    try stdout.flush();

And this for stdin:

    var stdin_buffer: [1024]u8 = undefined;
    var stdin_reader = std.Io.File.stdin().reader(io, &stdin_buffer);
    const stdin = &stdin_reader.interface;
    var buf: [1024]u8 = undefined;
    stdin.readSliceAll(&buf) catch |err| {
        if (err == std.Io.Reader.Error.EndOfStream) {
            std.log.info("End of stream reached", .{});
            std.log.info("Read buffer, stdin.seek={d}, stdin.end={d}, logicalPos={d}: \n{s}", .{ stdin.seek, stdin.end, stdin_reader.logicalPos(), buf[0..stdin_reader.logicalPos()] });
        } else {
            std.log.err("Error reading from stdin", .{});
        }
    };

Does this cover the basics for dealing with stdin and stdout?
Is logicalPos() the best way to find out how far the buffer got filled by the last call? (stdin.seek and stdin.end are both 0)
Is the .interface needed? (stdin() already returns a Reader so wouldn’t that already satisfy the interface?)

alanza July 18, 2026, 4:12pm 2

stdin() returns a File.Reader, which, perhaps confusingly, is an implementation of the Io.Reader interface, so it is a different type.

i think logicalPos is better understood as an offset into a file on disk. for stdin specifically, i don’t know what the behavior is…