Skip to content

NOTE

As APIs Bun.file e Bun.write documentadas nesta página são altamente otimizadas e representam a maneira recomendada de executar tarefas de sistema de arquivos usando o Bun. Para operações que ainda não estão disponíveis com Bun.file, como mkdir ou readdir, você pode usar a implementação quase completa do Bun do módulo node:fs.


Lendo arquivos (Bun.file())

Bun.file(path): BunFile

Crie uma instância BunFile com a função Bun.file(path). Um BunFile representa um arquivo carregado preguiçosamente; inicializá-lo não lê realmente o arquivo do disco.

ts
const foo = Bun.file("foo.txt"); // relativo ao cwd
foo.size; // número de bytes
foo.type; // tipo MIME

A referência segue a interface Blob, então o conteúdo pode ser lido em vários formatos.

ts
const foo = Bun.file("foo.txt");

await foo.text(); // conteúdo como string
await foo.json(); // conteúdo como objeto JSON
await foo.stream(); // conteúdo como ReadableStream
await foo.arrayBuffer(); // conteúdo como ArrayBuffer
await foo.bytes(); // conteúdo como Uint8Array

Referências de arquivo também podem ser criadas usando descritores de arquivo numéricos ou URLs file://.

ts
Bun.file(1234);
Bun.file(new URL(import.meta.url)); // referência ao arquivo atual

Um BunFile pode apontar para um local no disco onde um arquivo não existe.

ts
const notreal = Bun.file("notreal.txt");
notreal.size; // 0
notreal.type; // "text/plain;charset=utf-8"
const exists = await notreal.exists(); // false

O tipo MIME padrão é text/plain;charset=utf-8, mas pode ser sobrescrito passando um segundo argumento para Bun.file.

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

Por conveniência, o Bun expõe stdin, stdout e stderr como instâncias de BunFile.

ts
Bun.stdin; // somente leitura
Bun.stdout;
Bun.stderr;

Deletando arquivos (file.delete())

Você pode deletar um arquivo chamando a função .delete().

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

Escrevendo arquivos (Bun.write())

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

A função Bun.write é uma ferramenta multiuso para escrever payloads de todos os tipos no disco.

O primeiro argumento é o destination que pode ter qualquer um dos seguintes tipos:

  • string: Um caminho para um local no sistema de arquivos. Use o módulo "path" para manipular caminhos.
  • URL: Um descritor file://.
  • BunFile: Uma referência de arquivo.

O segundo argumento são os dados a serem escritos. Pode ser qualquer um dos seguintes:

  • string
  • Blob (incluindo BunFile)
  • ArrayBuffer ou SharedArrayBuffer
  • TypedArray (Uint8Array, etc.)
  • Response

Todas as permutações possíveis são tratadas usando as chamadas de sistema mais rápidas disponíveis na plataforma atual.

Ver syscalls

SaídaEntradaChamada de sistemaPlataforma
arquivoarquivocopy_file_rangeLinux
arquivopipesendfileLinux
pipepipespliceLinux
terminalarquivosendfileLinux
terminalterminalsendfileLinux
socketarquivo ou pipesendfile (se http, não https)Linux
arquivo (não existe)arquivo (caminho)clonefilemacOS
arquivo (existe)arquivofcopyfilemacOS
arquivoBlob ou stringwritemacOS
arquivoBlob ou stringwriteLinux

Para escrever uma string no disco:

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

Para copiar um arquivo para outro local no disco:

ts
const input = Bun.file("input.txt");
const output = Bun.file("output.txt"); // ainda não existe!
await Bun.write(output, input);

Para escrever um array de bytes no disco:

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

Para escrever um arquivo para stdout:

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

Para escrever o corpo de uma resposta HTTP no disco:

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

Escrita incremental com FileSink

O Bun fornece uma API nativa de escrita incremental de arquivos chamada FileSink. Para recuperar uma instância FileSink de um BunFile:

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

Para escrever incrementalmente no arquivo, chame .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");

Estes chunks serão armazenados em buffer internamente. Para liberar o buffer para o disco, use .flush(). Isso retorna o número de bytes liberados.

ts
writer.flush(); // escreve buffer para disco

O buffer também será liberado automaticamente quando o high water mark do FileSink for atingido; isto é, quando seu buffer interno estiver cheio. Este valor pode ser configurado.

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

Para liberar o buffer e fechar o arquivo:

ts
writer.end();

Note que, por padrão, o processo bun permanecerá ativo até que este FileSink seja explicitamente fechado com .end(). Para desativar este comportamento, você pode "unref" a instância.

ts
writer.unref();

// para "re-ref" mais tarde
writer.ref();

Diretórios

A implementação do node:fs do Bun é rápida, e ainda não implementamos uma API específica do Bun para ler diretórios. Por enquanto, você deve usar node:fs para trabalhar com diretórios no Bun.

Lendo diretórios (readdir)

Para ler um diretório no Bun, use readdir de node:fs.

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

// lê todos os arquivos no diretório atual
const files = await readdir(import.meta.dir);

Lendo diretórios recursivamente

Para ler recursivamente um diretório no Bun, use readdir com recursive: true.

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

// lê todos os arquivos no diretório atual, recursivamente
const files = await readdir("../", { recursive: true });

Criando diretórios (mkdir)

Para criar recursivamente um diretório, use mkdir em node:fs:

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

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

Benchmarks

A seguir está uma implementação de 3 linhas do comando Linux cat.

ts
// Uso
// 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));

Para executar o arquivo:

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

Ele roda 2x mais rápido que o GNU cat para arquivos grandes no Linux.


Referência

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 by www.bunjs.com.cn edit