Is the @constCast used correctly and safely with the 0.15 new io design?

pub fn writeFile(inputDir: ?std.fs.Dir, filePath: []const u8, fileContent: []const u8) !void {
    const dir = inputDir orelse std.fs.cwd();

    if (std.fs.path.dirname(filePath)) |dirpath| try dir.makePath(dirpath);

    var file = try dir.createFile(filePath, .{});
    defer file.close();

    var file_writer = file.writer(@constCast(fileContent)); // here
    file_writer.interface.end = fileContent.len; // and here
    try file_writer.interface.flush();

    try file.writeAll(fileContent);
}

give the writer a zero length buffer &.{}
then file_writer.interface.writeAll(fileContent)
no need to flush since the buffer is 0 length
no need to set interface.end

1 Like

I’m not all too familiar yet with the new IO interface, but this is definitely wrong:

var file_writer = file.writer(@constCast(fileContent)); // here

The writer() method wants to have a scratch buffer to batch written data, this cannot be the same memory as the data you want to write.

But AFAIK you’re massively overthinking it. If you just want to write some data blob to a file this should be enough:

    var file = try dir.createFile(filePath, .{});
    defer file.close();
    try file.writeAll(fileContent);
1 Like

File.writeAll is deprecated in 0.15. :smiley:

File.writeAll is deprecated in 0.15. :smiley:

Blargh, that sucks tbh. In that case the stdlib should definitely have a convenience wrapper which doesn’t require to deal with readers/writers if I just want to dump some data to a file.

E.g. if it’s more than 3 lines and 3 actions (open => write => close), then it’s already too much code bloat.

4 Likes

Agree, maybe File.writeAll should not be deprecated. It is okay to just re-write it.

I would expect that I need to get a reader or writer to a File object when I want to do some complex data-piping dance (e.g. building my own data processing pipeline which reads some data from somewhere, then runs some data conversion over it and then maybe does a compression and finally write to a file).

But for just dumping data to a file I would really expect that the File object offers the traditional blocking read/write convenience functions. Everything else is a special case that may require more code.

1 Like

I think your use case matches std.fs.Dir.writeFile.

No need to manually fiddle with Writers or Buffers.

5 Likes

This function is indeed not tagged as deprecated. But it looks it is still implemented in 0.14 way (it calls File.writeAll). So I don’t know if it is the good time to use it now.

If it is not marked as deprecated, you can assume it will be updated when the deprecated APIs it uses are removed.

I’ve been thinking about this a bit and it comes down to the old ‘stdlib as toolbox vs batteries included’ shism. In my ideal world, the stdlib would offer both:

A low-level layer with very flexible small building blocks which can be combined to implement exotic and/or high performance requirements, the downside may be that this low-level system requires detailed knowledge of how the system works under the hood, and it may be easy to use wrong or even expose footguns when used wrong. I see the new IO system as such a low-level building blocks layer.

But above that there should be convenience layers which implement specialized APIs for the “90% tasks” where the focus is on ease-of-use and not exposing too many footguns. Functions like std.fs.Dir.writeFile would definitely part of the convenience layer. E.g. when working with files I would only reach down to readers/writers when I need to tackle situations that can’t be done with the convenience functions - at the cost of more implementation work and higher risc of introducing bugs.

…those convenience layers could also be distributed as packages outside the stdlib, but they should still be maintained/curated by the Zig core team IMHO (to prevent ecosystem fragmentation like in the C and C++ world).

5 Likes

I skimmed over the init-std.Io branch. In the new std.Io implementations, the function std.Io.File.writeAll does not exist. Yet std.Io.Dir.writeFile is there with an additional io parameter, and the implementation is at least reworked to pass io along, but still calls the now not existing function std.Io.File.writeAll.

Definitely looks like work in progress at the moment.

1 Like