std.debug.print
will flush the output to stderr.
But with stdout write, I believe you need to call flush
on your own.
I thought about it, but no, that was not the reason.
os.write(line[0..]);
works as needed.
But it’s kinda strange… why does not compiler complain about os.write(line)
?..
When I change the relevant line of your program to os.write(line);
it works fine for me.
Did you try to pipe in the same file as out? Because this won’t work:
./snip-line 3 < in.txt > in.txt
It’s just going to erase your text file.
Hmm… now os.write(line)
works for me too.
Probably, I did something wrong before.
No, I did not do this:
$ history | grep "/skip-line"
2279 cd ../skip-line/
2282 ./skip-line
2285 ./skip-line
2286 ./skip-line 3 in.txt
2287 ./skip-line 3 < in.txt
2289 ./skip-line 3 < in.txt > out.txt
2293 ./skip-line 3 < in.txt > out.txt
2295 ./skip-line 3 < in.txt > out.txt
2297 ./skip-line 3 < in.txt
2301 ./skip-line 3 < in.txt > ooo
2303 ./skip-line 3 < in.txt > ooo
2305 ./skip-line 3 < in.txt > ooo
2306 ./skip-line 1 < in.txt > ooo
2307 ./skip-line 5 < in.txt > ooo
2308 ./skip-line 7 < in.txt > ooo
2310 ./skip-line 7 < in.txt > ooo
2312 ./skip-line 7 < in.txt > ooo
2314 ./skip-line 7 < in.txt > ooo
2317 ./skip-line 2 < in.txt > bbb
2321 ./skip-line 3 < a.txt > b.txt
2324 ./skip-line 5 < a.txt > c.txt
2327 ./skip-line 4 < a.txt > d.txt
2330 ./skip-line 4 < a.txt > d.txt
2332 ./skip-line 3 < a.txt > out.txt
But I didn’t do < a > a
, see history above.
Probably you were right.
The point is that initially I had buffered writer:
// var o = std.io.getStdOut();
// var os = o.writer();
var o = std.io.getStdOut();
var bw = std.io.bufferedWriter(o.writer());
var os = bw.writer();
With this buffered writer output file is always empty regardless of write()
arguments (buf[0..line.len]
, line[0..]
, line
). I just was lazy to search where flush
is sitting in the std lib, switched to unbuffered “mode” and did not realize that it was the change that made the program work correctly, but not playing with write()
arguments.
But still… I thought that upon program exit output file will be closed and flushed automatically… nope, this does not happen.
There was a good discussion awhile back about why Zig doesn’t do that.
wait… what has this to do with Zig
?..
here we have redirections handled by a shell (bash
in my case).
when a launched program exits, all open files are closed (fd 2 in this case)
and when a file is closed, OS should flush pending write ops, shouldn’t it?
I would even say “should”, yes, but they don’t, at least the POSIX-y ones don’t. I did think, for that reason, that you were referring to Zig adding this behavior, sorry about that.
I think there’s some sort of use-mention confusion happening here.
Ok, where is that flush()
living in all those fancy reader/writer interfaces?
A BufferedWriter has a flush()
method. It should be possible to open fds in line-buffered mode, but I’ve never done this, a userspace buffer is fine with me.
You can find details in std.fs.File. If you’re interested in opening a file handle in line buffered form, what you need will be in there.
Note
I tested it again with system call
write
. And it was flushed well.
TBH, I personally very seldom use fopen()/fread()/fwrite()/fclose
buffered wrappers, instead I prefer open()/read()/write()/close()
.
I got it:
var o = std.io.getStdOut();
var bw = std.io.bufferedWriter(o.writer());
var os = bw.writer();
var buf: [1024]u8 = undefined;
var cnt: u32 = 0;
while (try is.readUntilDelimiterOrEof(&buf, '\n')) |line| {
cnt += 1;
if (cnt == ln) continue;
std.debug.print("line #{}\n", .{cnt});
// _ = try os.write(buf[0..line.len]);
// _ = try os.write(line[0..]);
_ = try os.write(line);
_ = try os.write("\n");
}
try bw.flush();
works fine.
But it’s a bit brain out for me, I’d expect all ops to be available in the result of std.io.getStdOut();
see also this comment
I guess the Zig no hidden control flow ideal again? Flush seems like should be available on the Writer interface if it is expected. I do hope that it is at least consistent between OSes.
Be nice for the next person and flush before you exit.