The types of Reader and Writer

What are the types of
std.io.getStdOut().writer() and std.io.getStdIn().reader()?

I want to pass them as parameters to a function. Without using anytype :slight_smile:

const out: ??? = std.io.getStdOut().writer();
var in: ??? = std.io.getStdIn().reader();

My brains are to small I believe to comprehend what is golng on here inside the std.

Edit: when I print @TypeOf I get this…

io.GenericWriter(fs.File,error{NoSpaceLeft,DiskQuota,FileTooBig,InputOutput,DeviceBusy,InvalidArgument,AccessDenied,BrokenPipe,SystemResources,OperationAborted,NotOpenForWriting,LockViolation,WouldBlock,ConnectionResetByPeer,ProcessNotFound,NoDevice,Unexpected},(function 'write'))

Ok I foun out this:

const out: std.fs.File.Writer = std.io.getStdOut().writer();
const in: std.fs.File.Reader = std.io.getStdIn().reader();

is it correct to put these like this inside a function?

fn run(in: std.fs.File.Reader, out: std.fs.File.Writer) !void 
{
    // do my thing
}

It is just implementing a GenericWriter:

pub const  Writer = std.io.GenericWriter(std.fs.File, std.fs.File.WriteError, std.fs.File.write);
var writer: Writer = .{ .context = file };

I often use StreamSource in this scenario, it keeps it a little more flexible for arbitrary slices also.

1 Like

Just so you know, you’re talking about types that I am actively trying to eradicate from the standard library.

Post 0.15.0 you’ll have to use deprecatedWriter() / deprecatedReader() to get the same effect.

When you upgrade, you’ll have concrete types instead: std.fs.File.Writer / std.fs.File.Reader which are nicer for several reasons:

  • They are not generic
  • They support positional reads/writes, making seek() a no-op
  • They support seamlessly falling back to streaming reads/writes
  • They memoize the file size, avoiding redundant calls to stat()
  • They support using sendfile, copy_file_range, etc.
  • They support the new Io.Reader / Io.Writer API with conveniences such as take, peek, writableSlice, undo.

Just don’t forget to flush!

13 Likes

Ah yes, because of the coming io interface I suspect.
I copied your notes to my “notes.txt” :slight_smile: Thanks.
(writing an UCI chess engine… never done that)

0.15.dev
I recast my calls with this

var out = std.fs.File.stdout().writerStreaming(&.{});
pub inline fn Print( comptime format: []const u8, args: anytype) void {
    out.interface.print(format, args) catch return;
}
pub inline fn WriteAll( args: anytype) void {
    out.interface.writeAll(args) catch return;
}
var in = std.fs.File.stdin().readerStreaming(&.{});
fn Pause() void{
    WriteAll("Pause\r\n");
    var buf: [16]u8 =  [_]u8{0} ** 16;
    var c  : usize = 0;
    while (c <= 0) {
        c = in.interface.readVec(&.{&buf}) catch unreachable;
    }
}

or

fn Pause(msg : [] const u8 ) void{

    Print("\nPause  {s}\r\n",.{msg});
    var stdin = std.fs.File.stdin();
    var buf: [16]u8 =  [_]u8{0} ** 16;
    var c  : usize = 0;
    while (c == 0) {
        c = stdin.read(&buf) catch unreachable;
    }
}

inline fn advice (don’t do it)

args: anytype → bytes: []const u8

catch return → don’t ignore errors

[_]u8{0} ** 16 → @splat(0)

catch unreachable don’t do this

also recommend to run zig fmt

also instead of reading into a buffer, give your buffer to the reader and use take:

var in = std.fs.File.stdin().readerStreaming(&stdin_buffer);

// ...

const foo = try in.take(16);
6 Likes

Just like:

var c: usize = 0;

I always feel it is consistent to do:

var out: TYPE = std.fs.File.stdout().writerStreaming(&.{});
  • no inlining: Yes true! I gave up using that completely.
  • catch return, catch unreachable: Depends on the situation / usage / program.
  • zig fmt: That’s personal. All my files start with: zig fmt: off. It was thought by some the deck looked to cluttered.
  • [_]u8{0} ** 16 → @splat(0): Yes I like splat! the left statement looks crazy.

Anyway: For the 0.14 version I got it working with std.fs.File.Writer and std.fs.File.Reader.
When 0.15 is there I will have to study and rewrite.
The zig exe in the Windows terminal is a complete riddle for me (read: drama). I’ll probably start some rant inside the Explain section somewhere.
(mainly the insane slowness in not admin mode messing up my timers).

I only use it for my tests

it was for testing a snipset

In my terminal application in prod I do this.
Here it works in my context and has been thoroughly tested.
The unreachable function is correct.

var stdin = std.fs.File.stdin();
var stdout = std.fs.File.stdout().writerStreaming(&.{});

pub inline fn Print( comptime format: []const u8, args: anytype) void {
    stdout.interface.print(format,arg) catch  { } ;
}
pub inline fn WriteAll( args: [] const u8) void {
    stdout.interface.writeAll(args) catch { } ;
}

ex: pub fn gotoXY(x: usize, y: usize) void {
Print(“\x1b[{d};{d}H”, .{ x, y });
}

or WriteAll(“bonjour”);

I can also write this for terminal applications.

As for the stdin.read(&buf) instruction

very useful when you want to unravel keyboard keys on the fly.

reminder:
The compiler’s integrity check tells me if it’s consistent
That’s why I love ZIG.