#Issues appending to file

1 messages · Page 1 of 1 (latest)

charred marlin
#

Using zig 0.15.1 and trying to append to a file, but I seem to be overwriting from the beginning even with .seekFromEnd(0)

I've attached an example program that I'm working with here that creates a file, writes some text, closes it, opens it again and tries to append some text. However it overwrites from the beginning and I'm trying to figure out what I'm doing wrong here.

The output I'm getting from my example here is


Should Appendline to the file```
#

oh here's the attached file as a code block

const std = @import("std");

var stderr_buffer: [1024]u8 = undefined;
var stderr_writer = std.fs.File.stderr().writer(&stderr_buffer);
const stderr = &stderr_writer.interface;

pub fn main() !void {
    const cwd = std.fs.cwd();

    const file = try cwd.createFile("foo.txt", .{ .read = true });

    var fw_buf: [128]u8 = undefined;
    var fw_writer = file.writer(&fw_buf);
    const fw = &fw_writer.interface;
    try fw.writeAll("Writing this line to the file\n");
    try fw.flush();

    try file.seekTo(0);
    var fr_buf: [128]u8 = undefined;
    var fr_reader = file.reader(&fr_buf);
    const fr = &fr_reader.interface;

    var buf = [_]u8{0} ** 1024;
    _ = try fr.readSliceShort(&buf);
    try stderr.print("{s}\n", .{buf});
    try stderr.flush();

    file.close();

    const file2 = try cwd.openFile("foo.txt", .{ .mode = .read_write });
    defer file2.close();

    try file2.seekFromEnd(0);
    var fw2_buf: [128]u8 = undefined;
    var fw2_writer = file2.writer(&fw2_buf);
    const fw2 = &fw2_writer.interface;
    try fw2.writeAll("Should Append");
    try fw2.flush();

    try file2.seekTo(0);
    var fr2_buf: [128]u8 = undefined;
    var fr2_reader = file2.reader(&fr2_buf);
    var fr2 = &fr2_reader.interface;

    var buf2 = [_]u8{0} ** 1024;
    _ = try fr2.readSliceShort(&buf2);
    try stderr.print("{s}\n", .{buf2});
    try stderr.flush();
}
charred marlin
#

ah okay so I'm gathering file position doesn't actually seem to have an effect with Writer stuff. I can use like fw2_writer.SeekTo(50) to seek the writer somewhere else and then write, which will append, but Writer doesn't seem to have an equivalent of .seekFromEnd so still trying to figure out how to reliably get to the end here

charred marlin
#

okay well this seems to do it but I'd like to hear more experienced people's thoughts:

    var fw2_writer = file2.writer(&fw2_buf);
    // get to the end so we append
    try fw2_writer.seekTo(try file2.getEndPos());

    const fw2 = &fw2_writer.interface;
    try fw2.writeAll("Should Append");
    try fw2.flush();```
fathom spade
#

file writers and readers track their own position by default, they have their own seek functions you can use. You can change their mode to one of the streaming modes to use the file handles' position, which is what you are changing with the seek functions on File. The reasoning is the handles' position is global, when you have multiple readers/writers to file usually you want them to work independently.

FYI if you were ever using stdio and noticed the first read/write did nothing, thats because stdio requires streaming mode(s) as they arent normal files, when the reader/writer detect that they change modes automatically but abort the read/write.

also if you wonder why there are *_reading modes, those avoid more optimal but potentially unsupported/desired syscalls.

charred marlin
#

Ah okay that makes sense. Thank you for the explanation