Why are createFile/openFile methods of Dir instead of static functions like f.ex. os.fs.createFile()/openFile()
? Not knowing the details, this seems like an unnecessary departure from filesystem APIs in other languages and run-times.
use it like this it works fine
const data = @embedFile("./deps/curse/utils.zig");
var lines = std.mem.tokenize(u8, data, "\n");
var n : usize = 0;
while(lines.next()) |line| { ..... }
I donât know the reason for the design decision, but for me, itâs really convenient. cwd
will get me the current dir without me having to fuss about where exactly in the filesystem am I, or absolute versus relative paths, or forward versus back slashes, etc. I just get the current working dir and start creating / opening files there.
The file will be found in your program directory.
const file = try std.fs.cwd().createFile(
"junk_file.txt",
.{ .read = true },
);
defer file.close();
const bytes_written = try file.writeAll("Hello File!");
_ = bytes_written;
to know your base directory in which your program is located
const allocatory = std.heap.page_allocator;
const path = try std.fs.realpathAlloc(allocatory, ".");
defer allocatory.free(path);
std.debug.print("{s}\n", .{path});
Perhaps this decision is inline with Zigâs philosophy to minimize âhiddenâ code assumptions.
This âcwd()â term makes explicit the operating system imposed assumption that non-rooted file system pathnames pssed via system calls are taken relative to the operating systemâs maintained âcurrent worknig directoryâ of the calling process.
The current working directory is a pretty established part of an operating systemâs API though. Some might argue that a low-level language should expose the OS API as directly as possible. For example, I find Golangâs std library far better than Pythonâs and to large extent I think thatâs because Golang doesnât try to hide OS details.
Some people (and I guess I fall into this camp too) tend to always use absolute filenames, never relying on the current working dir, and I find it a little weird passing absolute filenames through cwdâŚ
I also seem to remember there is something related to WASM in here⌠Maybe WASM doesnât support relative path names, or somesuch; I donât really recall now.
Thanks for the replies! Digging into this a little more, I guess this exposes openat() which has the benefit that thereâs not a single global working directory per process which would lead to race conditions if different threads switch to different working directories.
Quite possibly related to WASI fs too, like mentioned above. Hereâs a HN thread discussing that.
Hereâs the PR where things started moving to be Dir
-based instead of using free functions like std.fs.createFile
:
It should now be clear the pattern that the standard library file system API is approaching. The API encourages programmers to take advantage of directory traversal via directory handles, for better general protection against Time Of Check, Time Of Use bugs across all Zig codebases.
Iâm not familiar enough with how it affects Time Of Check, Time Of Use bugs to speak to its success in that, though. I think a possibly better argument is that the Dir
-based API makes Zig code work with WASI by default. Iâve written a decent amount about that here:
As far as I can tell (but this is not documented anywhere, which is a problem imo and has been a point of confusion for a lot of people), the reason for having everything go through
Dir
is that it allows for that one API to be maximally cross-platformâeven for platforms that donât have the concept of an absolute path (e.g. WASM).
Thanks for the background, the latter issue seems pretty comprehensive!
I guess Iâd find banning absolute paths in the current openFile
API pretty off-putting. It seems like itâd introduce some extra âdeath by a thousand cutsâ friction to dealing with files thatâs not something Iâd like to deal with when just quickly throwing stuff together. (Similar to how I sometimes feel about Zigâs âwarnings-as-errorsâ for unused variables.) Like say passing in an absolute path to a command line tool⌠whatâs the right response to an absolute path then? Parse it into components, wrap it into a Dir
and then use that to open the file?
Yeah, I think that proposal is misguided and is (hopefully) very unlikely to be accepted. The Zig fs
API just takes some getting used to but getting WASI support pretty much everywhere for free is a really nice benefit of it.