#How to just fill as much of a buffer as possible with std.Io.Reader

1 messages · Page 1 of 1 (latest)

thorn hawk
#

In posix there is the read functon for sockets and fd_t's. And this read function fills the buffer as much as it can and returns the amount that it read.
Im wondering if the std.Io.Reader has something similar, just fills as much as possible and returns how much it read.

modern swallow
#

there's also fill and peekGreedy, which allow specifying a minimum

thorn hawk
#

could you provide an example, I find the std.Io.Reader to be very confusing

modern swallow
# thorn hawk could you provide an example, I find the std.Io.Reader to be **very** confusing
var buf: [4096]u8 = undefined;
var input = std.File.stdin.reader(&buf);

// do one read operation into the reader's internal buffer
try input.interface.fillMore();
std.debug.print("read {} bytes to internal buffer\n", .{input.interface.bufferedLen()});

// fill an external buffer, doing at most one read operation (but may just use bytes from the internal buffer, if there's enough)
var other_buf: [128]u8 = undefined;
var vec: [1][]u8 = .{&other_buf}; // needs to be mutable for Reasons:tm:, don't worry about it :)
const count = try input.interface.readVec(&vec);
std.debug.print("read {} bytes to external buffer\n", .{count});
#

i can give examples for fill and peekGreedy too if u want :)

thorn hawk
#

Well I would like to learn the std.Io.Reader so if you want to, but I wont hassel you

modern swallow
# thorn hawk Well I would like to learn the std.Io.Reader so if you want to, but I wont hass...
// ensure there are at least 10 bytes in the reader's internal buffer.
// `peekGreedy` returns the full content of the buffer, as opposed to `peek` and `take` which only return the requested number of bytes.
const bytes = try input.interface.peekGreedy(10);
std.debug.print("buffer contents: {s}\n", .{bytes});
// clear the buffer
try input.interface.tossBuffered();

// a different way of doing the same thing - can be more convenient sometimes
// eg. if u wanna call `takeInt`, `takeEnum`, etc multiple times, to parse some structured binary data
try input.interface.fill(10);
std.debug.print("buffer contents: {s}\n", .{input.interface.buffered()});
try input.interface.tossBuffered();
thorn hawk
#

oh ok, I see

#

but what is better?

#

or well it prob depends

modern swallow
#

depends on the situation

#

fill is a bit more low level than peek/take, but it's useful sometimes

thorn hawk
#

when is peekGreedy usefull?

modern swallow
#

uhhhh, tbh i don't think i've ever needed it giggle

thorn hawk
#

alright

#

well then fill it is

modern swallow
#

peekGreedy is also kinda low level tbh, usually u just use peek or take

thorn hawk
#

the thing with take it returns an error when its eof, does it just put the remaining in buffered()?

modern swallow
#

yea

#

take is a wrapper around peek and toss, and peek is a wrapper around fill

#

so if u call take, it'll first fill the buffer, then update the offsets to move past the data it's gonna return, then return the data

#

if there's not enough data, fill will fail, but it'll still put what it did read in the buffer

thorn hawk
#

but lets say I want to read an entire file can I just do fill(buffer.len) and then the entire content of the file is in the buffer?

#

I'd guess so

modern swallow
#

if the file fits in the buffer, yea

thorn hawk
#

alright

modern swallow
#

u may find allocRemaining more suited to ur needs for that tho

#

or streamRemaining into a Writer.Allocating, which lets u reuse the same allocated buffer multiple times

#

and there is also Dir.readFileAlloc if u just wanna read a file into memory without having to think too hard about it :)

thorn hawk
#

oh

#

never saw that xD

#

Even tho I've been using zig for like 7 months, I feel I always learn a new language xD

#

well thanks for all the awnsers, this was really helpfull ngl