注意 — 本页中记录的 Bun.file 和 Bun.write API 经过了高度优化,是使用 Bun 执行文件系统任务的推荐方式。对于 Bun.file 尚不可用的操作,例如 mkdir 或 readdir,您可以使用 Bun 几乎完整地实现了 node:fs 模块。
Bun 提供了一组优化的文件读写 API。
读取文件 (Bun.file())
Bun.file(path): BunFile
使用 Bun.file(path) 函数创建 BunFile 实例。BunFile 表示一个惰性加载的文件;初始化它并不会实际从磁盘读取文件。
const foo = Bun.file("foo.txt"); // relative to cwd
foo.size; // number of bytes
foo.type; // MIME type
该引用符合 Blob 接口,因此内容可以以各种格式读取。
const foo = Bun.file("foo.txt");
await foo.text(); // contents as a string
await foo.stream(); // contents as ReadableStream
await foo.arrayBuffer(); // contents as ArrayBuffer
await foo.bytes(); // contents as Uint8Array
文件引用也可以使用数字文件描述符或 file:// URL 创建。
Bun.file(1234);
Bun.file(new URL(import.meta.url)); // reference to the current file
BunFile 可以指向磁盘上不存在文件的位置。
const notreal = Bun.file("notreal.txt");
notreal.size; // 0
notreal.type; // "text/plain;charset=utf-8"
const exists = await notreal.exists(); // false
默认的 MIME 类型是 text/plain;charset=utf-8,但可以通过向 Bun.file 传递第二个参数来覆盖它。
const notreal = Bun.file("notreal.json", { type: "application/json" });
notreal.type; // => "application/json;charset=utf-8"
为方便起见,Bun 将 stdin、stdout 和 stderr 作为 BunFile 的实例公开。
Bun.stdin; // readonly
Bun.stdout;
Bun.stderr;
删除文件 (file.delete())
您可以通过调用 .delete() 函数来删除文件。
await Bun.file("logs.json").delete();
写入文件 (Bun.write())
Bun.write(destination, data): Promise<number>
Bun.write 函数是一个多功能工具,用于将各种有效负载写入磁盘。
第一个参数是 destination,它可以是以下任何一种类型:
string:文件系统上某个位置的路径。使用"path"模块来操作路径。URL:一个file://描述符。BunFile:一个文件引用。
第二个参数是要写入的数据。它可以是以下任何一种:
stringBlob(包括BunFile)ArrayBuffer或SharedArrayBufferTypedArray(Uint8Array等)Response
所有可能的排列都使用当前平台上最快的系统调用来处理。
查看系统调用
将字符串写入磁盘
const data = `It was the best of times, it was the worst of times.`;
await Bun.write("output.txt", data);
将文件复制到磁盘上的另一个位置
const input = Bun.file("input.txt");
const output = Bun.file("output.txt"); // doesn't exist yet!
await Bun.write(output, input);
将字节数组写入磁盘
const encoder = new TextEncoder();
const data = encoder.encode("datadatadata"); // Uint8Array
await Bun.write("output.txt", data);
将文件写入 stdout
const input = Bun.file("input.txt");
await Bun.write(Bun.stdout, input);
将 HTTP 响应体写入磁盘
const response = await fetch("https://bun.net.cn");
await Bun.write("index.html", response);
使用 FileSink 进行增量写入
Bun 提供了一个名为 FileSink 的原生增量文件写入 API。要从 BunFile 获取 FileSink 实例:
const file = Bun.file("output.txt");
const writer = file.writer();
要对文件进行增量写入,请调用 .write()。
const file = Bun.file("output.txt");
const writer = file.writer();
writer.write("it was the best of times\n");
writer.write("it was the worst of times\n");
这些块将在内部进行缓冲。要将缓冲区刷新到磁盘,请使用 .flush()。这会返回刷新的字节数。
writer.flush(); // write buffer to disk
当 FileSink 的高水位线达到时,缓冲区也会自动刷新;也就是说,当其内部缓冲区已满时。此值可以配置。
const file = Bun.file("output.txt");
const writer = file.writer({ highWaterMark: 1024 * 1024 }); // 1MB
要刷新缓冲区并关闭文件:
writer.end();
请注意,默认情况下,bun 进程将保持活动状态,直到此 FileSink 使用 .end() 显式关闭。要选择退出此行为,您可以“取消引用”该实例。
writer.unref();
// to "re-ref" it later
writer.ref();
目录
Bun 对 node:fs 的实现速度很快,我们尚未为读取目录实现 Bun 特定的 API。目前,您应该使用 node:fs 来处理 Bun 中的目录。
读取目录 (readdir)
要在 Bun 中读取目录,请使用 node:fs 中的 readdir。
import { readdir } from "node:fs/promises";
// read all the files in the current directory
const files = await readdir(import.meta.dir);
递归读取目录
要在 Bun 中递归读取目录,请使用带有 recursive: true 的 readdir。
import { readdir } from "node:fs/promises";
// read all the files in the current directory, recursively
const files = await readdir("../", { recursive: true });
创建目录 (mkdir)
要递归创建目录,请在 node:fs 中使用 mkdir
import { mkdir } from "node:fs/promises";
await mkdir("path/to/dir", { recursive: true });
基准测试
以下是 Linux cat 命令的 3 行实现。
// Usage
// $ bun ./cat.ts ./path-to-file
import { resolve } from "path";
const path = resolve(process.argv.at(-1));
await Bun.write(Bun.stdout, Bun.file(path));
运行文件
bun ./cat.ts ./path-to-file在 Linux 上,对于大文件,它的运行速度比 GNU cat 快 2 倍。

Reference
interface Bun {
stdin: BunFile;
stdout: BunFile;
stderr: BunFile;
file(path: string | number | URL, options?: { type?: string }): BunFile;
write(
destination: string | number | BunFile | URL,
input:
| string
| Blob
| ArrayBuffer
| SharedArrayBuffer
| TypedArray
| Response,
): Promise<number>;
}
interface BunFile {
readonly size: number;
readonly type: string;
text(): Promise<string>;
stream(): ReadableStream;
arrayBuffer(): Promise<ArrayBuffer>;
json(): Promise<any>;
writer(params: { highWaterMark?: number }): FileSink;
exists(): Promise<boolean>;
}
export interface FileSink {
write(
chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
): number;
flush(): number | Promise<number>;
end(error?: Error): number | Promise<number>;
start(options?: { highWaterMark?: number }): void;
ref(): void;
unref(): void;
}