zig-system-calls

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

System Calls & File I/O in Zig

Zig中的系统调用与文件I/O

Use
bun.sys
instead of
std.fs
or
std.posix
for cross-platform syscalls with proper error handling.
如需具备完善错误处理的跨平台系统调用,请使用
bun.sys
而非
std.fs
std.posix

bun.sys.File (Preferred)

bun.sys.File(推荐使用)

For most file operations, use the
bun.sys.File
wrapper:
zig
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.File
封装器:
zig
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?

Aspectbun.sysstd.fs/std.posix
Return Type
Maybe(T)
with detailed Error
Generic error union
WindowsFull support with libuv fallbackLimited/POSIX-only
Error Infoerrno, syscall tag, path, fderrno only
EINTRAutomatic retryManual handling
方面bun.sysstd.fs/std.posix
返回类型带详细错误信息的
Maybe(T)
通用错误联合类型
Windows支持完全支持,可回退到libuv支持有限/仅POSIX系统
错误信息错误码、系统调用标签、路径、文件描述符仅错误码
EINTR处理自动重试手动处理

Error Handling with Maybe(T)

基于Maybe(T)的错误处理

bun.sys
functions return
Maybe(T)
- a tagged union:
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.sys
函数返回
Maybe(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
bun.sys.File
doesn't meet your needs.
仅当
bun.sys.File
无法满足需求时,才使用以下操作。

Opening 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.DIRECTORY
zig
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.DIRECTORY

Reading & 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.FD
:
zig
fd.close();  // Asserts on error (use in defer)

// Or if you need error info:
if (fd.closeAllowingBadFileDescriptor(null)) |err| {
    // handle error
}
关闭操作在
bun.FD
上实现:
zig
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
bun.DirIterator
instead of
std.fs.Dir.Iterator
:
zig
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.DirIterator
而非
std.fs.Dir.Iterator
zig
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:
bun.sys
has limited socket support. For network I/O:
  • Non-blocking sockets: Use
    uws.Socket
    (libuwebsockets) exclusively
  • Pipes/blocking I/O: Use
    PipeReader.zig
    and
    PipeWriter.zig
Available in bun.sys:
zig
sys.setsockopt(fd, level, optname, value)
sys.socketpair(domain, socktype, protocol, nonblocking_status)
Do NOT use
bun.sys
for socket read/write - use
uws.Socket
instead.
注意
bun.sys
对Socket的支持有限。如需网络I/O:
  • 非阻塞Socket:请完全使用
    uws.Socket
    (基于libuwebsockets)
  • 管道/阻塞I/O:请使用
    PipeReader.zig
    PipeWriter.zig
bun.sys中可用的Socket操作:
zig
sys.setsockopt(fd, level, optname, value)
sys.socketpair(domain, socktype, protocol, nonblocking_status)
请勿使用
bun.sys
进行Socket读/写操作——请改用
uws.Socket

Other 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 string
zig
const err: bun.sys.Error = ...;
err.errno      // 原始错误码值
err.getErrno() // 转换为std.posix.E枚举类型
err.syscall    // 失败的系统调用(Tag枚举)
err.fd         // 可选:文件描述符
err.path       // 可选:路径字符串

Key Points

关键点

  • Prefer
    bun.sys.File
    wrapper for most file operations
  • Use low-level
    bun.sys
    functions only when needed
  • Use
    bun.O.*
    flags instead of
    std.os.O.*
  • Handle
    Maybe(T)
    with switch or
    .unwrap()
  • Use
    defer fd.close()
    for cleanup
  • EINTR is handled automatically in most functions
  • For sockets, use
    uws.Socket
    not
    bun.sys
  • 大多数文件操作优先使用
    bun.sys.File
    封装器
  • 仅在必要时使用底层
    bun.sys
    函数
  • 使用
    bun.O.*
    标志而非
    std.os.O.*
  • 通过switch或
    .unwrap()
    处理
    Maybe(T)
  • 使用
    defer fd.close()
    进行资源清理
  • 大多数函数会自动处理EINTR错误
  • Socket操作请使用
    uws.Socket
    而非
    bun.sys