Writing bytes is the opposite of reading them.
The simplest write operation takes a slice and sends its contents to a file or stream.
try file.writeAll(bytes);writeAll continues writing until every byte has been written or an error occurs.
A complete example:
const std = @import("std");
pub fn main() !void {
const cwd = std.fs.cwd();
const file = try cwd.createFile(
"output.txt",
.{},
);
defer file.close();
const message = "hello, zig\n";
try file.writeAll(message);
}After running the program, output.txt contains:
hello, zigThe call:
cwd.createFile("output.txt", .{})creates a new file for writing.
The returned value is a file handle. As before, the handle must eventually be closed.
The variable:
const message = "hello, zig\n";is a string literal.
A Zig string literal is stored as bytes. Its type is a pointer to a constant array of u8 values with a sentinel byte at the end.
writeAll accepts any byte slice, including string literals.
The operation:
try file.writeAll(message);does not add formatting, terminators, or extra bytes. The exact bytes from the slice are written.
A larger example copies standard input into a file.
const std = @import("std");
pub fn main() !void {
const stdin = std.io.getStdIn();
const cwd = std.fs.cwd();
const output = try cwd.createFile(
"copy.txt",
.{},
);
defer output.close();
var buffer: [1024]u8 = undefined;
while (true) {
const n = try stdin.read(&buffer);
if (n == 0)
break;
try output.writeAll(buffer[0..n]);
}
}This program has the same structure as the previous reading examples:
- create a resource
- allocate a buffer
- read bytes
- write bytes
- repeat until end-of-file
The important point is that writing may also be partial.
Some operating system calls write fewer bytes than requested. The method:
writeAllhandles this automatically.
The lower-level operation:
writereturns the number of bytes actually written:
const n = try file.write(bytes);Like read, correct code must use the returned value.
Most programs should prefer writeAll unless partial writes are required explicitly.
Standard output is also a writable stream.
const stdout = std.io.getStdOut();
try stdout.writeAll("hello\n");Or through a writer:
try std.io.getStdOut().writer().print(
"value = {}\n",
.{42},
);The difference is important:
writeAllwrites raw bytesprintformats values into bytes first
Programs often combine both styles.
Exercise 13-9. Write a program that writes the numbers 1 through 10 into a file.
Exercise 13-10. Write a program that copies one file into another using only read and write, not readAll or writeAll.
Exercise 13-11. Modify the copy program so it appends instead of replacing the output file.
Exercise 13-12. Write a program that writes all command-line arguments into a file, one per line.