Skip to content

Instantly share code, notes, and snippets.

@LordMZTE
Created June 25, 2023 15:07
Show Gist options
  • Save LordMZTE/ce8348536c7ba6f7d7323f9d7f1b49a8 to your computer and use it in GitHub Desktop.
Save LordMZTE/ce8348536c7ba6f7d7323f9d7f1b49a8 to your computer and use it in GitHub Desktop.
const std = @import("std");
pub fn main() !void {
std.debug.print("== Buffer ==\n", .{});
try readWithBuf();
std.debug.print("== Allocator ==\n", .{});
try readAlloc();
}
fn readWithBuf() !void {
const f = try std.fs.cwd().openFile("test.zig", .{});
defer f.close();
var buf: [1024]u8 = undefined;
// Die expression im loop header gibt hier einen optionalen typ zurück (?[]u8). Dieser wird
// gecapturt (|line|). Das sort dafür, das der loop läuft, bis hier null zurückgegeben wird.
//
// Line ist ein slice in buf.
while (try f.reader().readUntilDelimiterOrEof(&buf, '\n')) |line| {
std.debug.print("line: {s}\n", .{line});
}
}
fn readAlloc() !void {
// Allocator erstellen. Hier nehme ich einen GPA (GeneralPurposeAllocator).
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
// gpa.deinit() gibt true zurück, wenn es einen memory leak gibt und gibt dann aus,
// wo das geleakte memory allocated wurde (geil, oder?). Das ignoriere ich hier explizit
defer _ = gpa.deinit();
const alloc = gpa.allocator();
const f = try std.fs.cwd().openFile("test.zig", .{});
defer f.close();
// std.ArrayList ist eine funktion, die den element typ nimmt, und einen typ für eine
// entsprechende liste zurück gibt, so macht zig generics.
var alist = std.ArrayList(u8).init(alloc);
defer alist.deinit();
// Ich verwende hier einen labelled block um in der loop condition mehrere expressions
// auszuführen. Mit break :blk x; wird vom block ein wert zurückgegeben (in diesem fall
// ob daten gelesen wurden).
while (blk: {
// readUntilDelimiterArrayList leert die ArrayList, wobei diese aber ihr allocated memory
// wiederverwendet. so werden allocate-calls gespart.
// Das API ist in master schöner :D
// Man könnte auch `readUntilDelimiterOrEofAlloc` nehmen, das wäre dann so ähnlich wie die
// variente mit dem buffer, das ist aber ineffizient.
f.reader().readUntilDelimiterArrayList(
&alist,
'\n',
// kein limit
std.math.maxInt(usize),
) catch |e| switch (e) { // error handeln
error.EndOfStream => break :blk false, // wenn wir am ende sind, loop stoppen
else => return e, // bei anderen errors: den error zum caller geben
};
break :blk true;
}) {
std.debug.print("line: {s}\n", .{alist.items});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment