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

file i/o

41 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 upload with FormData and Bun.serve

To upload files over HTTP with Bun, use the FormData API. Create an HTTP server with Bun.serve that serves an HTML form with enctype="multipart/form-data". The form sends a POST request with form data to an endpoint. On the server, call .formData() on the incoming Request to asynchronously parse its contents into a FormData instance. Use .get() to extract field values. File fields are Blob objects. Write the Blob to disk using Bun.write().

Bun.write() with Blob

Bun.write() can write a Blob object to disk. The first argument is the file path as a string, and the second argument is the Blob to write.

File upload example with Bun.serve

Example showing file upload handling with Bun.serve: ```ts const server = Bun.serve({ port: 4000, async fetch(req) { const url = new URL(req.url); if (url.pathname === "/") return new Response(Bun.file("index.html"), { headers: { "Content-Type": "text/html", }, }); if (url.pathname === "/action") { const formdata = await req.formData(); const name = formdata.get("name"); const profilePicture = formdata.get("profilePicture"); if (!profilePicture) throw new Error("Must upload a profile picture."); await Bun.write("profilePicture.png", profilePicture); return new Response("Success"); } return new Response("Not Found", { status: 404 }); }, }); ``` This example demonstrates parsing FormData from a POST request and writing an uploaded file to disk.

File I/O APIs

Bun provides the following file I/O APIs: Bun.file() for reading files, Bun.write() for writing files, Bun.stdin for standard input, Bun.stdout for standard output, and Bun.stderr for standard error.

Writing Archive to disk with Bun.write

Use Bun.write() to write an archive to disk. Pass the archive object as the second argument. Example: await Bun.write('output.tar', archive) for uncompressed tar or await Bun.write('output.tar.gz', compressed) for gzipped tar.

Bun.file() creates BunFile instances

Bun.file(path) returns a BunFile instance that represents a lazily-loaded file. The path can be a string relative to cwd, a file descriptor (number), or a file:// URL. Initializing a BunFile does not read the file from disk.

BunFile properties: size and type

A BunFile has two properties: size (number of bytes) and type (MIME type). The default MIME type is 'text/plain;charset=utf-8'. Override the type by passing a second argument to Bun.file() with an options object containing a type property.

BunFile read methods

BunFile conforms to the Blob interface and supports: text() returns Promise<string>, json() returns Promise<any>, arrayBuffer() returns Promise<ArrayBuffer>, bytes() returns Promise<Uint8Array>, and stream() returns ReadableStream.

BunFile.exists() and delete() methods

BunFile provides exists() which returns Promise<boolean> to check if a file exists, and delete() which returns Promise<void> to delete a file. A BunFile can point to a location where a file does not exist.

Bun.stdin, stdout, stderr standard streams

Bun exposes stdin, stdout, and stderr as BunFile instances. stdin is readonly, while stdout and stderr are writable.

Bun.write() function signature and parameters

Bun.write(destination, data) returns Promise<number>. destination can be a string path, URL (file://), or BunFile. data can be string, Blob (including BunFile), ArrayBuffer, SharedArrayBuffer, TypedArray (Uint8Array, et al.), or Response.

Bun.write() uses platform-optimized system calls

Bun.write() handles each combination of output and input with the fastest available system call on the current platform. On Linux it uses copy_file_range, sendfile, or splice depending on the input/output types. On macOS it uses clonefile or fcopyfile for files, and write for Blob/string.

FileSink incremental writing API

BunFile.writer(params?) returns a FileSink for incremental file writing. FileSink has methods: write(chunk) returns number, flush() returns number | Promise<number>, end(error?) returns number | Promise<number>, start(options?) with optional highWaterMark, ref(), and unref().

FileSink highWaterMark configuration

FileSink buffers chunks internally and auto-flushes when the high water mark is reached. Configure the high water mark by passing { highWaterMark: bytes } to the writer() method or start() method. Default behavior keeps the bun process alive until FileSink is closed with end().

FileSink ref() and unref() methods

FileSink.unref() opts out of the default behavior that keeps the bun process alive. FileSink.ref() can be used to 're-ref' an unreffed FileSink later.

Read directory with node:fs readdir

Use readdir from 'node:fs/promises' to read directories in Bun. Pass { recursive: true } option to readdir() to recursively read all files in a directory and subdirectories.

Create directory with node:fs mkdir

Use mkdir from 'node:fs/promises' to create directories. Pass { recursive: true } option to mkdir() to recursively create all parent directories.

Example: Bun.file() basic usage

const foo = Bun.file("foo.txt"); foo.size; // number of bytes foo.type; // MIME type

Example: Reading file contents

const foo = Bun.file("foo.txt"); await foo.text(); // contents as a string await foo.json(); // contents as a JSON object foo.stream(); // contents as ReadableStream await foo.arrayBuffer(); // contents as ArrayBuffer await foo.bytes(); // contents as Uint8Array

Example: BunFile from descriptor or URL

Bun.file(1234); // from file descriptor Bun.file(new URL(import.meta.url)); // reference to the current file

Example: Override BunFile MIME type

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

Example: Check if file exists and delete

const notreal = Bun.file("notreal.txt"); const exists = await notreal.exists(); // false await Bun.file("logs.json").delete();

Example: Bun.write() string to disk

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

Example: Bun.write() copy file

const input = Bun.file("input.txt"); const output = Bun.file("output.txt"); // doesn't exist yet! await Bun.write(output, input);

Example: Bun.write() byte array

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

Example: Bun.write() to stdout

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

Example: Bun.write() HTTP response

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

Example: FileSink incremental writing

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

Example: FileSink with custom highWaterMark

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

Example: FileSink ref and unref

const file = Bun.file("output.txt"); const writer = file.writer(); writer.unref(); // to "re-ref" it later writer.ref();

Example: Read directory with readdir

import { readdir } from "node:fs/promises"; // read all the files in the current directory const files = await readdir(import.meta.dir);

Example: Read directory recursively

import { readdir } from "node:fs/promises"; // read all the files in the current directory, recursively const files = await readdir("../", { recursive: true });

Example: Create directory recursively

import { mkdir } from "node:fs/promises"; await mkdir("path/to/dir", { recursive: true });

Example: Linux cat command implementation

// Usage: 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));

TypeScript interface: Bun file i/o methods

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

TypeScript interface: BunFile

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

TypeScript interface: FileSink

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.file and Bun.write are heavily optimized

The Bun.file and Bun.write APIs are heavily optimized and recommended for file operations. For operations not covered by these APIs, such as mkdir or readdir, use Bun's nearly complete implementation of the node:fs module.

Serving files with Bun.file in routes

In Bun.serve routes, you can use Bun.file(path) to lazily load and serve a file. Example: '/favicon.ico': Bun.file('./favicon.ico'). The file is loaded into memory only when the route is accessed.

node:fs fully implemented

node:fs is fully implemented. 98% of Node.js's test suite passes. Stats objects lack the Temporal.Instant getters (atimeInstant and friends).

fetch write response to file

You can use Bun.write to write the response body directly to a file on disk.

Give your agent this brain