# Help migrating to Zig 0.16.0 IO model: std.Io.File.Reader fails during readSliceAll

**URL:** <https://ziggit.dev/t/help-migrating-to-zig-0-16-0-io-model-std-io-file-reader-fails-during-readsliceall/17314>\
**Category:** Help\
**Tags:** zig-0-16\
**Created:** [August 21, 2026, 8:17am UTC](https://ziggit.dev/t/help-migrating-to-zig-0-16-0-io-model-std-io-file-reader-fails-during-readsliceall/17314 "2026-08-21T08:17:09Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gbelsalvador](https://ziggit.dev/user_avatar/ziggit.dev/gbelsalvador/32/9951_2.png) [@Gbelsalvador](https://ziggit.dev/u/Gbelsalvador)\
**Post date:** [August 21, 2026, 8:17am UTC](https://ziggit.dev/t/help-migrating-to-zig-0-16-0-io-model-std-io-file-reader-fails-during-readsliceall/17314/1 "2026-08-21T08:17:09Z")

</div>

Hello everyone,  
I am currently working on migrating a small vector database storage engine to the new Zig 0.16.0 IO system. I am hitting a runtime issue (test failure) when trying to read a binary struct from a file using std.Io.File.Reader.  
Here is the context: I have a Manifest structure that I write to disk and then try to read back inside a test block.

## My Code:

```zig
const std = @import("std");

pub const Manifest = struct {
    magic: [7]u8,
    version: u32,
    dimension: u32,
    vector_count: u64,
    metric: u8,
    quantization: u8,
    reserved: [6]u8,
};

pub fn writeManifest(
    io: anytype,
    path: []const u8,
    manifest: Manifest,
) !void {
    var file = try std.Io.Dir.cwd().createFile(io, path, .{});
    defer file.close(io);

    var write_buf: [1024]u8 = undefined;
    var w = file.writer(io, &write_buf);
    
    try w.interface.writeAll(std.mem.asBytes(&manifest));
}

pub fn readManifest(
    io: anytype,
    path: []const u8,
) !Manifest {
    var file = try std.Io.Dir.cwd().openFile(io, path, .{});
    defer file.close(io);

    var manifest: Manifest = undefined;
    const bytes = std.mem.asBytes(&manifest);

    var read_buf: [1024]u8 = undefined;
    var r = file.reader(io, &read_buf);

    // This is where it fails at runtime
    try r.interface.readSliceAll(bytes);

    return manifest;
}

test "manifest persistence" {
    const io = std.testing.io;
    const file_path = "test.manifest";
    defer std.Io.Dir.cwd().deleteFile(io, file_path) catch {};

    const manifest = Manifest{
        .magic = .{ 'Z', 'V', 'E', 'C', 'T', 'O', 'R' },
        .version = 1,
        .dimension = 768,
        .vector_count = 10000,
        .metric = 0,
        .quantization = 1,
        .reserved = .{0} ** 6,
    };

    try writeManifest(io, file_path, manifest);
    const loaded = try readManifest(io, file_path);

    try std.testing.expectEqual(manifest.dimension, loaded.dimension);
}

```

## The Error:

When running zig test src/storage.zig, the compilation succeeds, but the test fails at runtime exactly on the line:  
try r.interface.readSliceAll(bytes);  
It seems like the reader is returning an unexpected EndOfStream or a failing error code, even though the file is successfully created and written to beforehand.

## My Questions:

1. What is the idiomatic way in Zig 0.16.0 to read/write a raw struct from a file using the new [std.Io](http://std.Io) event loop / subsystem?
2. Am I misusing the file.reader(io, &read\_buf) stack buffers? Should they be sized or aligned differently for readSliceAll to succeed?

Any guidance on how the new intrusive Reader/Writer interfaces orchestrate unbuffered or buffered file reading in 0.16 would be greatly appreciated!  
Thanks in advance!

---

<div class="post-metadata">

**Author:** ![kudu](https://ziggit.dev/user_avatar/ziggit.dev/kudu/32/2802_2.png) [@kudu](https://ziggit.dev/u/kudu)\
**Post date:** [August 21, 2026, 8:48am UTC](https://ziggit.dev/t/help-migrating-to-zig-0-16-0-io-model-std-io-file-reader-fails-during-readsliceall/17314/2 "2026-08-21T08:48:07Z")

</div>

I think you just need to flush.

```zig
    try w.flush();

```

---

<div class="post-metadata">

**Author:** ![Gbelsalvador](https://ziggit.dev/user_avatar/ziggit.dev/gbelsalvador/32/9951_2.png) [@Gbelsalvador](https://ziggit.dev/u/Gbelsalvador)\
**Post date:** [August 22, 2026, 2:03am UTC](https://ziggit.dev/t/help-migrating-to-zig-0-16-0-io-model-std-io-file-reader-fails-during-readsliceall/17314/3 "2026-08-22T02:03:42Z")

</div>

Thanks a lot, I just tested it and it works.

---

<div class="post-metadata">

**Author:** ![spiffyk](https://ziggit.dev/user_avatar/ziggit.dev/spiffyk/32/7202_2.png) [@spiffyk](https://ziggit.dev/u/spiffyk)\
**Post date:** [August 22, 2026, 6:36am UTC](https://ziggit.dev/t/help-migrating-to-zig-0-16-0-io-model-std-io-file-reader-fails-during-readsliceall/17314/4 "2026-08-22T06:36:16Z")

</div>

> [@Gbelsalvador](#):
>
> ```zig
> pub const Manifest = struct {
> magic: [7]u8,
> version: u32,
> dimension: u32,
> vector_count: u64,
> metric: u8,
> quantization: u8,
> reserved: [6]u8,
> };
> 
> ```

You need to make this an `extern struct` to make its ABI stable, otherwise your program will break unexpectedly, as Zig doesn’t provide any guarantees for the layout of a (non-`extern`) `struct`. Once you do that, you’ll also get an implicit padding byte between `magic` and `version`, which you should make explicit to be able to control its value (probably zero it out?)

Welcome to Ziggit!

---

<div class="post-metadata">

**Author:** ![dulzeedg](https://ziggit.dev/user_avatar/ziggit.dev/dulzeedg/32/9585_2.png) [@dulzeedg](https://ziggit.dev/u/dulzeedg)\
**Post date:** [August 24, 2026, 3:07pm UTC](https://ziggit.dev/t/help-migrating-to-zig-0-16-0-io-model-std-io-file-reader-fails-during-readsliceall/17314/5 "2026-08-24T15:07:44Z")

</div>

Seems like I’m actually learning—I thought of that too.
