Hey, can you tell me how to open a file in Zig? It’s my first time learning a systems programming language.
I am trying to read a file 8 bytes at a time.
I look up many sources, and they all use std.fs.cwd to get a file object and go from there, but in the documentation, it says it is deprecated in favor of Io.Dir.cwd.
And finally I came up with this solution with the help form Introduction to Zig
You do. In zig, you often use defer for this. If you know that the end of the scope is the best place for the close, you can put
defer file.close(io);
immediately after your cwd.openFile() line. This keeps it close to the open, where it’s easy to see that it’s closure is being taken care of.
This is an aspect of zig language design. In particular, it will facilitate various implementations of IO, like threaded or other async implementations, in addition to the straightforward route we’re often used to. The reason for having to always pass the io, instead of letting it “live under the hood somewhere” is, in part, to make it clear that a given operation you’re calling on DOES indeed DO I/O. It’s similar to the allocator motif in zig.
Hmnn… now I see @vulpesx is replying… he’ll probably do a better job of hitting your “implementation” question, anyway….
I don’t recommend learning zig with the nightly release, especially if you’re not interested in any WIP features such as the new Io interface.
Depends, most OS’s will close them for you when your program terminates. Though they also have a limit for the number of files open so it is recommended to close them. you can just defer file.close()might take an io parameter
what feels wrong, is it just the verbosity, or is it something else.
“Wrong” in quotes as it either depends, or is just not the best.
A “wrong” thing you are doing is getting stdout in the initialisation of a global var. This makes your code break on Windows. Global var initial values need to be comptime known, and windows stdout is not.
Only matters if you care about windows.
Another “wrong” thing is giving your reader a buffer, then using functions that outputs to another buffer.
The first buffer is not being used, and it is quite small.
Larger buffer = less syscalls = faster.
I would give it a larger buffer, eg 1024 (1kb), you can then reader.take(8) to get 8 bytes. this way you only need one buffer, and it can be larger to minimise syscalls. Be warned that it gives you a reference to its buffer, it might be overwritten on your next call to the reader, (that won’t happen until it reaches the end of the buffer). So depending on what you are doing you might want a second buffer so you can keep the data around while still using the reader.
Oh, yes, and this. It does look like you’re using master (0.16), right? In this case, I think you’ll find a lot of various “how-to” documentation out there that references the old fs.File stuff which will soon be deprecated - later, you use std.fs.File.stdout(), but that’s for your stdout, so that’s probably fine. Just beware that if you’re in this 0.16-forward space, then fs.File will be deprecated to io.File. Refer to the official zig documentation, which does spell out quite a lot of the Io stuff, even if verbosity might grow in time.
I installed v0.16.0-dev because Ziglings needs that version to run.
Since I use Linux, the current approach works for me, but I want to clarify is it generally considered good practice to place it in local scope regardless?
I am learning Zig by building an HTTP server from scratch.
And i got the wanted answer.
Thank you to everyone who has offered help here.