zig-system-calls
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSystem Calls & File I/O in Zig
Zig中的系统调用与文件I/O
Use instead of or for cross-platform syscalls with proper error handling.
bun.sysstd.fsstd.posix如需具备完善错误处理的跨平台系统调用,请使用而非或。
bun.sysstd.fsstd.posixbun.sys.File (Preferred)
bun.sys.File(推荐使用)
For most file operations, use the wrapper:
bun.sys.Filezig
const File = bun.sys.File;
const file = switch (File.open(path, bun.O.RDWR, 0o644)) {
.result => |f| f,
.err => |err| return .{ .err = err },
};
defer file.close();
// Read/write
_ = try file.read(buffer).unwrap();
_ = try file.writeAll(data).unwrap();
// Get file info
const stat = try file.stat().unwrap();
const size = try file.getEndPos().unwrap();
// std.io compatible
const reader = file.reader();
const writer = file.writer();对于大多数文件操作,请使用封装器:
bun.sys.Filezig
const File = bun.sys.File;
const file = switch (File.open(path, bun.O.RDWR, 0o644)) {
.result => |f| f,
.err => |err| return .{ .err = err },
};
defer file.close();
// 读/写操作
_ = try file.read(buffer).unwrap();
_ = try file.writeAll(data).unwrap();
// 获取文件信息
const stat = try file.stat().unwrap();
const size = try file.getEndPos().unwrap();
// 兼容std.io
const reader = file.reader();
const writer = file.writer();Complete Example
完整示例
zig
const File = bun.sys.File;
pub fn writeFile(path: [:0]const u8, data: []const u8) File.WriteError!void {
const file = switch (File.open(path, bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o664)) {
.result => |f| f,
.err => |err| return err.toError(),
};
defer file.close();
_ = switch (file.writeAll(data)) {
.result => {},
.err => |err| return err.toError(),
};
}zig
const File = bun.sys.File;
pub fn writeFile(path: [:0]const u8, data: []const u8) File.WriteError!void {
const file = switch (File.open(path, bun.O.WRONLY | bun.O.CREAT | bun.O.TRUNC, 0o664)) {
.result => |f| f,
.err => |err| return err.toError(),
};
defer file.close();
_ = switch (file.writeAll(data)) {
.result => {},
.err => |err| return err.toError(),
};
}Why bun.sys?
为什么选择bun.sys?
| Aspect | bun.sys | std.fs/std.posix |
|---|---|---|
| Return Type | | Generic error union |
| Windows | Full support with libuv fallback | Limited/POSIX-only |
| Error Info | errno, syscall tag, path, fd | errno only |
| EINTR | Automatic retry | Manual handling |
| 方面 | bun.sys | std.fs/std.posix |
|---|---|---|
| 返回类型 | 带详细错误信息的 | 通用错误联合类型 |
| Windows支持 | 完全支持,可回退到libuv | 支持有限/仅POSIX系统 |
| 错误信息 | 错误码、系统调用标签、路径、文件描述符 | 仅错误码 |
| EINTR处理 | 自动重试 | 手动处理 |
Error Handling with Maybe(T)
基于Maybe(T)的错误处理
bun.sysMaybe(T)zig
const sys = bun.sys;
// Pattern 1: Switch on result/error
switch (sys.read(fd, buffer)) {
.result => |bytes_read| {
// use bytes_read
},
.err => |err| {
// err.errno, err.syscall, err.fd, err.path
if (err.getErrno() == .AGAIN) {
// handle EAGAIN
}
},
}
// Pattern 2: Unwrap with try (converts to Zig error)
const bytes = try sys.read(fd, buffer).unwrap();
// Pattern 3: Unwrap with default
const value = sys.stat(path).unwrapOr(default_stat);bun.sysMaybe(T)zig
const sys = bun.sys;
// 方式1:匹配结果/错误
switch (sys.read(fd, buffer)) {
.result => |bytes_read| {
// 使用bytes_read
},
.err => |err| {
// err.errno, err.syscall, err.fd, err.path
if (err.getErrno() == .AGAIN) {
// 处理EAGAIN错误
}
},
}
// 方式2:用try解包(转换为Zig错误)
const bytes = try sys.read(fd, buffer).unwrap();
// 方式3:带默认值的解包
const value = sys.stat(path).unwrapOr(default_stat);Low-Level File Operations
底层文件操作
Only use these when doesn't meet your needs.
bun.sys.File仅当无法满足需求时,才使用以下操作。
bun.sys.FileOpening Files
打开文件
zig
const sys = bun.sys;
// Use bun.O flags (cross-platform normalized)
const fd = switch (sys.open(path, bun.O.RDONLY, 0)) {
.result => |fd| fd,
.err => |err| return .{ .err = err },
};
defer fd.close();
// Common flags
bun.O.RDONLY, bun.O.WRONLY, bun.O.RDWR
bun.O.CREAT, bun.O.TRUNC, bun.O.APPEND
bun.O.NONBLOCK, bun.O.DIRECTORYzig
const sys = bun.sys;
// 使用bun.O标志(跨平台标准化)
const fd = switch (sys.open(path, bun.O.RDONLY, 0)) {
.result => |fd| fd,
.err => |err| return .{ .err = err },
};
defer fd.close();
// 常用标志
bun.O.RDONLY, bun.O.WRONLY, bun.O.RDWR
bun.O.CREAT, bun.O.TRUNC, bun.O.APPEND
bun.O.NONBLOCK, bun.O.DIRECTORYReading & Writing
读/写操作
zig
// Single read (may return less than buffer size)
switch (sys.read(fd, buffer)) {
.result => |n| { /* n bytes read */ },
.err => |err| { /* handle error */ },
}
// Read until EOF or buffer full
const total = try sys.readAll(fd, buffer).unwrap();
// Position-based read/write
sys.pread(fd, buffer, offset)
sys.pwrite(fd, data, offset)
// Vector I/O
sys.readv(fd, iovecs)
sys.writev(fd, iovecs)zig
// 单次读取(返回字节数可能小于缓冲区大小)
switch (sys.read(fd, buffer)) {
.result => |n| { /* 读取了n字节 */ },
.err => |err| { /* 处理错误 */ },
}
// 读取至EOF或缓冲区满
const total = try sys.readAll(fd, buffer).unwrap();
// 基于位置的读/写
sys.pread(fd, buffer, offset)
sys.pwrite(fd, data, offset)
// 向量I/O
sys.readv(fd, iovecs)
sys.writev(fd, iovecs)File Info
文件信息
zig
sys.stat(path) // Follow symlinks
sys.lstat(path) // Don't follow symlinks
sys.fstat(fd) // From file descriptor
sys.fstatat(fd, path)
// Linux-only: faster selective stat
sys.statx(path, &.{ .size, .mtime })zig
sys.stat(path) // 跟随符号链接
sys.lstat(path) // 不跟随符号链接
sys.fstat(fd) // 通过文件描述符获取
sys.fstatat(fd, path)
// Linux专属:更快的选择性获取文件信息
sys.statx(path, &.{ .size, .mtime })Path Operations
路径操作
zig
sys.unlink(path)
sys.unlinkat(dir_fd, path)
sys.rename(from, to)
sys.renameat(from_dir, from, to_dir, to)
sys.readlink(path, buf)
sys.readlinkat(fd, path, buf)
sys.link(T, src, dest)
sys.linkat(src_fd, src, dest_fd, dest)
sys.symlink(target, dest)
sys.symlinkat(target, dirfd, dest)
sys.mkdir(path, mode)
sys.mkdirat(dir_fd, path, mode)
sys.rmdir(path)zig
sys.unlink(path)
sys.unlinkat(dir_fd, path)
sys.rename(from, to)
sys.renameat(from_dir, from, to_dir, to)
sys.readlink(path, buf)
sys.readlinkat(fd, path, buf)
sys.link(T, src, dest)
sys.linkat(src_fd, src, dest_fd, dest)
sys.symlink(target, dest)
sys.symlinkat(target, dirfd, dest)
sys.mkdir(path, mode)
sys.mkdirat(dir_fd, path, mode)
sys.rmdir(path)Permissions
权限管理
zig
sys.chmod(path, mode)
sys.fchmod(fd, mode)
sys.fchmodat(fd, path, mode, flags)
sys.chown(path, uid, gid)
sys.fchown(fd, uid, gid)zig
sys.chmod(path, mode)
sys.fchmod(fd, mode)
sys.fchmodat(fd, path, mode, flags)
sys.chown(path, uid, gid)
sys.fchown(fd, uid, gid)Closing File Descriptors
关闭文件描述符
Close is on :
bun.FDzig
fd.close(); // Asserts on error (use in defer)
// Or if you need error info:
if (fd.closeAllowingBadFileDescriptor(null)) |err| {
// handle error
}关闭操作在上实现:
bun.FDzig
fd.close(); // 出错时触发断言(建议在defer中使用)
// 如需获取错误信息:
if (fd.closeAllowingBadFileDescriptor(null)) |err| {
// 处理错误
}Directory Operations
目录操作
zig
var buf: bun.PathBuffer = undefined;
const cwd = try sys.getcwd(&buf).unwrap();
const cwdZ = try sys.getcwdZ(&buf).unwrap(); // Zero-terminated
sys.chdir(path, destination)zig
var buf: bun.PathBuffer = undefined;
const cwd = try sys.getcwd(&buf).unwrap();
const cwdZ = try sys.getcwdZ(&buf).unwrap(); // 以0结尾的字符串
sys.chdir(path, destination)Directory Iteration
目录遍历
Use instead of :
bun.DirIteratorstd.fs.Dir.Iteratorzig
var iter = bun.iterateDir(dir_fd);
while (true) {
switch (iter.next()) {
.result => |entry| {
if (entry) |e| {
const name = e.name.slice();
const kind = e.kind; // .file, .directory, .sym_link, etc.
} else {
break; // End of directory
}
},
.err => |err| return .{ .err = err },
}
}请使用而非:
bun.DirIteratorstd.fs.Dir.Iteratorzig
var iter = bun.iterateDir(dir_fd);
while (true) {
switch (iter.next()) {
.result => |entry| {
if (entry) |e| {
const name = e.name.slice();
const kind = e.kind; // .file, .directory, .sym_link等
} else {
break; // 遍历结束
}
},
.err => |err| return .{ .err = err },
}
}Socket Operations
Socket操作
Important: has limited socket support. For network I/O:
bun.sys- Non-blocking sockets: Use (libuwebsockets) exclusively
uws.Socket - Pipes/blocking I/O: Use and
PipeReader.zigPipeWriter.zig
Available in bun.sys:
zig
sys.setsockopt(fd, level, optname, value)
sys.socketpair(domain, socktype, protocol, nonblocking_status)Do NOT use for socket read/write - use instead.
bun.sysuws.Socket注意:对Socket的支持有限。如需网络I/O:
bun.sys- 非阻塞Socket:请完全使用(基于libuwebsockets)
uws.Socket - 管道/阻塞I/O:请使用和
PipeReader.zigPipeWriter.zig
bun.sys中可用的Socket操作:
zig
sys.setsockopt(fd, level, optname, value)
sys.socketpair(domain, socktype, protocol, nonblocking_status)请勿使用进行Socket读/写操作——请改用。
bun.sysuws.SocketOther Operations
其他操作
zig
sys.ftruncate(fd, size)
sys.lseek(fd, offset, whence)
sys.dup(fd)
sys.dupWithFlags(fd, flags)
sys.fcntl(fd, cmd, arg)
sys.pipe()
sys.mmap(...)
sys.munmap(memory)
sys.access(path, mode)
sys.futimens(fd, atime, mtime)
sys.utimens(path, atime, mtime)zig
sys.ftruncate(fd, size)
sys.lseek(fd, offset, whence)
sys.dup(fd)
sys.dupWithFlags(fd, flags)
sys.fcntl(fd, cmd, arg)
sys.pipe()
sys.mmap(...)
sys.munmap(memory)
sys.access(path, mode)
sys.futimens(fd, atime, mtime)
sys.utimens(path, atime, mtime)Error Type
错误类型
zig
const err: bun.sys.Error = ...;
err.errno // Raw errno value
err.getErrno() // As std.posix.E enum
err.syscall // Which syscall failed (Tag enum)
err.fd // Optional: file descriptor
err.path // Optional: path stringzig
const err: bun.sys.Error = ...;
err.errno // 原始错误码值
err.getErrno() // 转换为std.posix.E枚举类型
err.syscall // 失败的系统调用(Tag枚举)
err.fd // 可选:文件描述符
err.path // 可选:路径字符串Key Points
关键点
- Prefer wrapper for most file operations
bun.sys.File - Use low-level functions only when needed
bun.sys - Use flags instead of
bun.O.*std.os.O.* - Handle with switch or
Maybe(T).unwrap() - Use for cleanup
defer fd.close() - EINTR is handled automatically in most functions
- For sockets, use not
uws.Socketbun.sys
- 大多数文件操作优先使用封装器
bun.sys.File - 仅在必要时使用底层函数
bun.sys - 使用标志而非
bun.O.*std.os.O.* - 通过switch或处理
.unwrap()Maybe(T) - 使用进行资源清理
defer fd.close() - 大多数函数会自动处理EINTR错误
- Socket操作请使用而非
uws.Socketbun.sys