Skip to content

NOTE

Le API Bun.file e Bun.write documentate in questa pagina sono fortemente ottimizzate e rappresentano il modo consigliato per eseguire operazioni sul file system usando Bun. Per operazioni non ancora disponibili con Bun.file, come mkdir o readdir, puoi usare l'implementazione quasi completa di Bun del modulo node:fs.


Leggere file (Bun.file())

Bun.file(path): BunFile

Crea un'istanza BunFile con la funzione Bun.file(path). Un BunFile rappresenta un file caricato lazy; inizializzarlo non legge effettivamente il file dal disco.

ts
const foo = Bun.file("foo.txt"); // relativo a cwd
foo.size; // numero di byte
foo.type; // tipo MIME

Il riferimento è conforme all'interfaccia Blob, quindi i contenuti possono essere letti in vari formati.

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

await foo.text(); // contenuti come stringa
await foo.json(); // contenuti come oggetto JSON
await foo.stream(); // contenuti come ReadableStream
await foo.arrayBuffer(); // contenuti come ArrayBuffer
await foo.bytes(); // contenuti come Uint8Array

I riferimenti ai file possono essere creati anche usando file descriptor numerici o URL file://.

ts
Bun.file(1234);
Bun.file(new URL(import.meta.url)); // riferimento al file corrente

Un BunFile può puntare a una posizione sul disco dove un file non esiste.

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

Il tipo MIME predefinito è text/plain;charset=utf-8, ma può essere sovrascritto passando un secondo argomento a Bun.file.

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

Per comodità, Bun espone stdin, stdout e stderr come istanze di BunFile.

ts
Bun.stdin; // readonly
Bun.stdout;
Bun.stderr;

Eliminare file (file.delete())

Puoi eliminare un file chiamando la funzione .delete().

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

Scrivere file (Bun.write())

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

La funzione Bun.write è un multi-strumento per scrivere payload di ogni tipo su disco.

Il primo argomento è la destination che può avere uno dei seguenti tipi:

  • string: Un percorso a una posizione sul file system. Usa il modulo "path" per manipolare i percorsi.
  • URL: Un descrittore file://.
  • BunFile: Un riferimento a un file.

Il secondo argomento sono i dati da scrivere. Può essere uno dei seguenti:

  • string
  • Blob (incluso BunFile)
  • ArrayBuffer o SharedArrayBuffer
  • TypedArray (Uint8Array, ecc.)
  • Response

Tutte le possibili permutazioni sono gestite usando le system call più veloci disponibili sulla piattaforma corrente.

Vedi system call

OutputInputSystem callPiattaforma
filefilecopy_file_rangeLinux
filepipesendfileLinux
pipepipespliceLinux
terminalfilesendfileLinux
terminalterminalsendfileLinux
socketfile o pipesendfile (se http, non https)Linux
file (non esiste)file (percorso)clonefilemacOS
file (esiste)filefcopyfilemacOS
fileBlob o stringawritemacOS
fileBlob o stringawriteLinux

Per scrivere una stringa su disco:

ts
const data = `Era il migliore dei tempi, era il peggiore dei tempi.`;
await Bun.write("output.txt", data);

Per copiare un file in un'altra posizione su disco:

ts
const input = Bun.file("input.txt");
const output = Bun.file("output.txt"); // non esiste ancora!
await Bun.write(output, input);

Per scrivere un array di byte su disco:

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

Per scrivere un file su stdout:

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

Per scrivere il body di una response HTTP su disco:

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

Scrittura incrementale con FileSink

Bun fornisce un'API nativa di scrittura incrementale di file chiamata FileSink. Per recuperare un'istanza FileSink da un BunFile:

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

Per scrivere incrementalmente nel file, chiama .write().

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

writer.write("era il migliore dei tempi\n");
writer.write("era il peggiore dei tempi\n");

Questi chunk verranno memorizzati internamente nel buffer. Per flushare il buffer su disco, usa .flush(). Questo restituisce il numero di byte flushati.

ts
writer.flush(); // scrive il buffer su disco

Il buffer verrà anche auto-flushato quando viene raggiunta la high water mark del FileSink; cioè, quando il suo buffer interno è pieno. Questo valore può essere configurato.

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

Per flushare il buffer e chiudere il file:

ts
writer.end();

Nota che, per impostazione predefinita, il processo bun rimarrà attivo finché questo FileSink non viene esplicitamente chiuso con .end(). Per rinunciare a questo comportamento, puoi fare "unref" dell'istanza.

ts
writer.unref();

// per "re-ref" più tardi
writer.ref();

Directory

L'implementazione di node:fs di Bun è veloce e non abbiamo ancora implementato un'API specifica di Bun per leggere le directory. Per ora, dovresti usare node:fs per lavorare con le directory in Bun.

Leggere directory (readdir)

Per leggere una directory in Bun, usa readdir da node:fs.

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

// leggi tutti i file nella directory corrente
const files = await readdir(import.meta.dir);

Leggere directory ricorsivamente

Per leggere ricorsivamente una directory in Bun, usa readdir con recursive: true.

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

// leggi tutti i file nella directory corrente, ricorsivamente
const files = await readdir("../", { recursive: true });

Creare directory (mkdir)

Per creare ricorsivamente una directory, usa mkdir in node:fs:

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

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

Benchmark

La seguente è un'implementazione di 3 righe del comando cat di Linux.

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

Per eseguire il file:

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

Esegue 2x più velocemente di GNU cat per file di grandi dimensioni su Linux.


Riferimento

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 a cura di www.bunjs.com.cn