new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Bun · Runtime · all subjects

bun apis/file i/o

27 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

File I/O APIs: Bun.file and Bun.write

Bun provides file I/O through Bun.file() for reading files and Bun.write() for writing files. Bun also provides Bun.stdin, Bun.stdout, and Bun.stderr for standard streams.

BunFile properties and methods

A BunFile instance has read-only properties size (number of bytes) and type (MIME type, defaults to 'text/plain;charset=utf-8'). Methods include text() returning Promise<string>, json() returning Promise<any>, stream() returning ReadableStream, arrayBuffer() returning Promise<ArrayBuffer>, bytes() returning Promise<Uint8Array>, exists() returning Promise<boolean>, delete() for deleting the file, and writer(params) for incremental writing.

Bun.file() MIME type override

Pass a second argument to Bun.file() with a type property to override the default MIME type. For example, Bun.file('notreal.json', { type: 'application/json' }) sets the type to 'application/json;charset=utf-8'.

Bun.stdin, Bun.stdout, Bun.stderr exposed as BunFile

Bun exposes stdin (readonly), stdout, and stderr as BunFile instances for convenient access to standard I/O streams.

Bun.write() multi-purpose file writing function

Bun.write(destination, data) writes data to disk and returns Promise<number> with the number of bytes written. The destination can be a string path, URL (file://), or BunFile. The data can be string, Blob (including BunFile), ArrayBuffer, SharedArrayBuffer, TypedArray (Uint8Array, etc.), or Response. Bun selects the fastest system call for each combination on the current platform.

Bun.write() system calls by platform

On Linux: file-to-file uses copy_file_range, pipe output uses sendfile, splice for pipe-to-pipe, socket output with http (not https) uses sendfile. On macOS: non-existent file destination uses clonefile, existing file uses fcopyfile, Blob or string input uses write. File-to-Blob or file-to-string combinations on any platform use write syscall.

FileSink incremental writing API

FileSink is a native incremental file writing API. Retrieve it from a BunFile using file.writer(). Call write(chunk) to add data (string, ArrayBufferView, ArrayBuffer, or SharedArrayBuffer), flush() to flush to disk returning number or Promise<number>, and end(error?) to flush and close the file. Configure the highWaterMark option to control buffer size before auto-flush.

FileSink ref() and unref() for process lifecycle

By default, a FileSink keeps the bun process alive until explicitly closed with end(). Call unref() to opt out of this behavior, allowing the process to exit while the FileSink is open. Call ref() to re-enable the behavior and keep the process alive.

Reading files with BunFile interface

To read file contents: await bunFile.text() for string, await bunFile.json() for JSON object, bunFile.stream() for ReadableStream, await bunFile.arrayBuffer() for ArrayBuffer, await bunFile.bytes() for Uint8Array.

Copying files with Bun.write()

To copy a file, create BunFile instances for source and destination, then call await Bun.write(destination, source). The destination file does not need to exist yet.

Writing string to file example

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

Writing byte array to file example

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

Writing file to stdout example

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

Writing HTTP response to disk example

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

FileSink incremental write example

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'); writer.flush(); // write buffer to disk writer.end(); // flush and close

FileSink highWaterMark configuration

Configure the highWaterMark option when creating a FileSink to set the internal buffer size before auto-flushing. For example, file.writer({ highWaterMark: 1024 * 1024 }) sets a 1MB buffer.

Reading directory with node:fs readdir

Import readdir from 'node:fs/promises' to read directories. For recursive reading, use readdir(path, { recursive: true }). Example: const files = await readdir(import.meta.dir);

Creating directory with node:fs mkdir

Import mkdir from 'node:fs/promises' to create directories. Use mkdir(path, { recursive: true }) to recursively create all parent directories. Example: await mkdir('path/to/dir', { recursive: true });

Bun.file() with non-existent file

A BunFile can reference a file that does not exist on disk. Such a reference has size 0 and type 'text/plain;charset=utf-8'. Call exists() to check if the file actually exists on disk.

BunFile.delete() removes a file

Call .delete() on a BunFile instance to delete the file. Example: await Bun.file('logs.json').delete();

Bun file I/O API reference signature

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

BunFile interface signature

interface BunFile { readonly size: number; readonly type: string; text(): Promise<string>; stream(): ReadableStream; arrayBuffer(): Promise<ArrayBuffer>; json(): Promise<any>; bytes(): Promise<Uint8Array>; writer(params: { highWaterMark?: number }): FileSink; exists(): Promise<boolean>; delete(): Promise<void>; }

FileSink interface signature

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

Linux cat command implementation with Bun

import { resolve } from 'path'; const path = resolve(process.argv.at(-1)); await Bun.write(Bun.stdout, Bun.file(path)); Run with: bun ./cat.ts ./path-to-file This 3-line implementation runs 2x faster than GNU cat for large files on Linux.

Bun.file() and Bun.write() are heavily optimized

Bun.file() and Bun.write() APIs are heavily optimized and are the recommended way to work with files in Bun. For operations they do not cover (such as mkdir or readdir), use Bun's nearly complete implementation of the node:fs module.

Bun.file() creates a lazy-loaded file reference

Bun.file(path) creates a BunFile instance that represents a file without immediately reading it from disk. The path can be a string (relative to cwd), a file descriptor number, or a file:// URL. A BunFile conforms to the Blob interface and can point to a non-existent file location.

Bun.pathToFileURL() converts path to file URL

Bun.pathToFileURL(path: string): URL converts an absolute path to a file:// URL. Example: Bun.pathToFileURL("/foo/bar.txt") returns "file:///foo/bar.txt".

Give your agent this brain