0

I'm creating a simple program that reads from a file and then process that file.

I saw a pattern for reading using a std.io.bufferedReader and std.io.fixedBufferStream().writer()

So I'm trying to create a function to return both Writer and Reader.

For doing such thing I'm trying to create a struct which the fields are from type std.io.Writer and std.io.Reader but they are functions that return the type and not an actual type.

So, how can I create it?

My current looks like:

const std = @import("std");

const BufferedWriterAndReader = struct {
    writer: std.io.Writer,
    reader: std.io.Reader,
};

fn getBufferedWriterAndReader(path: []u8) BufferedWriterAndReader {
    var file = try std.fs.cwd().openFile(path, .{});
    defer file.close();
    var buf_reader = std.io.bufferedReader(file.reader());
    var file_reader = buf_reader.reader();

    var lines: [256]u8 = undefined;
    var lines_buf = std.io.fixedBufferStream(&lines);
    var lines_writer = lines_buf.writer();
    return BufferedWriterAndReader{
        .writer = lines_writer,
        .reader = file_reader,
    };
}

pub fn main() !void {
    getBufferedWriterAndReader("strategy.txt");
}
Douglas Correa
  • 1,015
  • 12
  • 25
  • 1
    You need to rethink this whole approach. `lines` is a local array which will not be valid after the function returns, yet a pointer to this array is handed to `fixedBufferStream`. If you don't prematurely close the input file (with the misplaced `defer`, you still need to close the file from `main`. `BufferedWriterAndReader` can fail, so it needs to return an error union. – ad absurdum Jun 21 '23 at 17:23

1 Answers1

1

What you are trying to do here won't work for different reasons:

    var file = try std.fs.cwd().openFile(path, .{});
    defer file.close();

You are closing the file at the end of the function. Therefor the reader/writer won't be able to read/write to the file anymore.

The buf_reader, lines_buf also sit on the stack/use stack memory, so they get invalidated at the end of the function call.

So I would suggest that you take a step back and rethink what you actually want to do here. For example if you just want a simple solution and don't care about performance, just read the entire file onto the heap (file.readToEndAlloc())

Now to actually answer your question:

You can check out the type of a value at compile-time. So you could just do this to query the exact type:

    @compileLog(@TypeOf(lines_writer));
    @compileLog(@TypeOf(file_reader));

(Now the results of that will look complicated. And there is no easy way to simplify the types given that zig has no builtin inheritance)

QuantumDeveloper
  • 737
  • 6
  • 15