NOTE
API Bun.file и Bun.write, документированные на этой странице, сильно оптимизированы и представляют рекомендуемый способ выполнения задач файловой системы с помощью Bun. Для операций, которые ещё не доступны с Bun.file, таких как mkdir или readdir, вы можете использовать почти полную реализацию Bun модуля node:fs.
Чтение файлов (Bun.file())
Bun.file(path): BunFile
Создайте экземпляр BunFile с помощью функции Bun.file(path). BunFile представляет лениво загружаемый файл; его инициализация фактически не читает файл с диска.
const foo = Bun.file("foo.txt"); // относительно cwd
foo.size; // количество байт
foo.type; // MIME-типСсылка соответствует интерфейсу Blob, поэтому содержимое можно читать в различных форматах.
const foo = Bun.file("foo.txt");
await foo.text(); // содержимое как строка
await foo.json(); // содержимое как JSON-объект
await foo.stream(); // содержимое как ReadableStream
await foo.arrayBuffer(); // содержимое как ArrayBuffer
await foo.bytes(); // содержимое как Uint8ArrayСсылки на файлы также могут быть созданы с использованием числовых дескрипторов файлов или URL file://.
Bun.file(1234);
Bun.file(new URL(import.meta.url)); // ссылка на текущий файлBunFile может указывать на место на диске, где файл не существует.
const notreal = Bun.file("notreal.txt");
notreal.size; // 0
notreal.type; // "text/plain;charset=utf-8"
const exists = await notreal.exists(); // falseMIME-тип по умолчанию — 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; // только для чтения
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
Все возможные перестановки обрабатываются с использованием самых быстрых системных вызовов на текущей платформе.
См. системные вызовы
| Вывод | Ввод | Системный вызов | Платформа |
|---|---|---|---|
| файл | файл | copy_file_range | Linux |
| файл | pipe | sendfile | Linux |
| pipe | pipe | splice | Linux |
| терминал | файл | sendfile | Linux |
| терминал | терминал | sendfile | Linux |
| сокет | файл или pipe | sendfile (если http, не https) | Linux |
| файл (не существует) | файл (путь) | clonefile | macOS |
| файл (существует) | файл | fcopyfile | macOS |
| файл | Blob или строка | write | macOS |
| файл | Blob или строка | write | Linux |
Чтобы записать строку на диск:
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"); // ещё не существует!
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.com");
await Bun.write("index.html", response);Инкрементная запись с FileSink
Bun предоставляет нативный API инкрементной записи файлов под названием FileSink. Чтобы получить экземпляр FileSink из BunFile:
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(); // записать буфер на дискБуфер также будет автоматически сброшен при достижении high water mark FileSink; то есть, когда его внутренний буфер заполнен. Это значение можно настроить.
const file = Bun.file("output.txt");
const writer = file.writer({ highWaterMark: 1024 * 1024 }); // 1MBЧтобы сбросить буфер и закрыть файл:
writer.end();Обратите внимание, что по умолчанию процесс bun будет оставаться активным до тех пор, пока этот FileSink не будет явно закрыт с помощью .end(). Чтобы отказаться от этого поведения, вы можете "unref" экземпляр.
writer.unref();
// чтобы "re-ref" его позже
writer.ref();Директории
Реализация node:fs в Bun быстрая, и мы ещё не реализовали специфичный для Bun API для чтения директорий. Пока что вы должны использовать node:fs для работы с директориями в Bun.
Чтение директорий (readdir)
Чтобы прочитать директорию в Bun, используйте readdir из node:fs.
import { readdir } from "node:fs/promises";
// прочитать все файлы в текущей директории
const files = await readdir(import.meta.dir);Рекурсивное чтение директорий
Чтобы рекурсивно прочитать директорию в Bun, используйте readdir с recursive: true.
import { readdir } from "node:fs/promises";
// прочитать все файлы в текущей директории рекурсивно
const files = await readdir("../", { recursive: true });Создание директорий (mkdir)
Чтобы рекурсивно создать директорию, используйте mkdir в node:fs:
import { mkdir } from "node:fs/promises";
await mkdir("path/to/dir", { recursive: true });Бенчмарки
Ниже приведена 3-строчная реализация команды Linux cat.
// Использование
// 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Он работает в 2 раза быстрее, чем GNU cat для больших файлов на Linux.
Ссылка
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;
}