Skip to content

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 представляет лениво загружаемый файл; его инициализация фактически не читает файл с диска.

ts
const foo = Bun.file("foo.txt"); // относительно cwd
foo.size; // количество байт
foo.type; // MIME-тип

Ссылка соответствует интерфейсу Blob, поэтому содержимое можно читать в различных форматах.

ts
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://.

ts
Bun.file(1234);
Bun.file(new URL(import.meta.url)); // ссылка на текущий файл

BunFile может указывать на место на диске, где файл не существует.

ts
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.

ts
const notreal = Bun.file("notreal.json", { type: "application/json" });
notreal.type; // => "application/json;charset=utf-8"

Для удобства Bun предоставляет stdin, stdout и stderr как экземпляры BunFile.

ts
Bun.stdin; // только для чтения
Bun.stdout;
Bun.stderr;

Удаление файлов (file.delete())

Вы можете удалить файл, вызвав функцию .delete().

ts
await Bun.file("logs.json").delete();

Запись файлов (Bun.write())

Bun.write(destination, data): Promise<number>

Функция Bun.write — это многофункциональный инструмент для записи полезных данных всех видов на диск.

Первый аргумент — это destination, который может иметь любой из следующих типов:

  • string: Путь к месту в файловой системе. Используйте модуль "path" для манипуляции путями.
  • URL: Дескриптор file://.
  • BunFile: Ссылка на файл.

Второй аргумент — это данные для записи. Это может быть любое из следующего:

  • string
  • Blob (включая BunFile)
  • ArrayBuffer или SharedArrayBuffer
  • TypedArray (Uint8Array и т.д.)
  • Response

Все возможные перестановки обрабатываются с использованием самых быстрых системных вызовов на текущей платформе.

См. системные вызовы

ВыводВводСистемный вызовПлатформа
файлфайлcopy_file_rangeLinux
файлpipesendfileLinux
pipepipespliceLinux
терминалфайлsendfileLinux
терминалтерминалsendfileLinux
сокетфайл или pipesendfile (если http, не https)Linux
файл (не существует)файл (путь)clonefilemacOS
файл (существует)файлfcopyfilemacOS
файлBlob или строкаwritemacOS
файлBlob или строкаwriteLinux

Чтобы записать строку на диск:

ts
const data = `It was the best of times, it was the worst of times.`;
await Bun.write("output.txt", data);

Чтобы скопировать файл в другое место на диске:

ts
const input = Bun.file("input.txt");
const output = Bun.file("output.txt"); // ещё не существует!
await Bun.write(output, input);

Чтобы записать массив байтов на диск:

ts
const encoder = new TextEncoder();
const data = encoder.encode("datadatadata"); // Uint8Array
await Bun.write("output.txt", data);

Чтобы записать файл в stdout:

ts
const input = Bun.file("input.txt");
await Bun.write(Bun.stdout, input);

Чтобы записать тело HTTP-ответа на диск:

ts
const response = await fetch("https://bun.com");
await Bun.write("index.html", response);

Инкрементная запись с FileSink

Bun предоставляет нативный API инкрементной записи файлов под названием FileSink. Чтобы получить экземпляр FileSink из BunFile:

ts
const file = Bun.file("output.txt");
const writer = file.writer();

Для инкрементной записи в файл вызовите .write().

ts
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(). Это возвращает количество сброшенных байтов.

ts
writer.flush(); // записать буфер на диск

Буфер также будет автоматически сброшен при достижении high water mark FileSink; то есть, когда его внутренний буфер заполнен. Это значение можно настроить.

ts
const file = Bun.file("output.txt");
const writer = file.writer({ highWaterMark: 1024 * 1024 }); // 1MB

Чтобы сбросить буфер и закрыть файл:

ts
writer.end();

Обратите внимание, что по умолчанию процесс bun будет оставаться активным до тех пор, пока этот FileSink не будет явно закрыт с помощью .end(). Чтобы отказаться от этого поведения, вы можете "unref" экземпляр.

ts
writer.unref();

// чтобы "re-ref" его позже
writer.ref();

Директории

Реализация node:fs в Bun быстрая, и мы ещё не реализовали специфичный для Bun API для чтения директорий. Пока что вы должны использовать node:fs для работы с директориями в Bun.

Чтение директорий (readdir)

Чтобы прочитать директорию в Bun, используйте readdir из node:fs.

ts
import { readdir } from "node:fs/promises";

// прочитать все файлы в текущей директории
const files = await readdir(import.meta.dir);

Рекурсивное чтение директорий

Чтобы рекурсивно прочитать директорию в Bun, используйте readdir с recursive: true.

ts
import { readdir } from "node:fs/promises";

// прочитать все файлы в текущей директории рекурсивно
const files = await readdir("../", { recursive: true });

Создание директорий (mkdir)

Чтобы рекурсивно создать директорию, используйте mkdir в node:fs:

ts
import { mkdir } from "node:fs/promises";

await mkdir("path/to/dir", { recursive: true });

Бенчмарки

Ниже приведена 3-строчная реализация команды Linux cat.

ts
// Использование
// 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));

Для запуска файла:

bash
bun ./cat.ts ./path-to-file

Он работает в 2 раза быстрее, чем GNU cat для больших файлов на Linux.


Ссылка

ts
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;
}

Bun от www.bunjs.com.cn