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");
}
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()
)
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)