diff options
Diffstat (limited to 'docs/api/file-io.md')
-rw-r--r-- | docs/api/file-io.md | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/docs/api/file-io.md b/docs/api/file-io.md new file mode 100644 index 000000000..a79f6ad80 --- /dev/null +++ b/docs/api/file-io.md @@ -0,0 +1,256 @@ +{% callout %} +**Note** — Bun also provides an [almost complete](/docs/runtime/nodejs) implementation of the Node.js `fs` module, documented [here](https://nodejs.org/api/fs.html). This page only documents Bun-native APIs. +{% /callout %} + +Bun provides a set of optimized APIs for reading and writing files. + +## Reading files + +`Bun.file(path): BunFile` + +Create a `BunFile` instance with the `Bun.file(path)` function. A `BunFile` represents represents a lazily-loaded file; initializing it does not actually read the file from disk. + +```ts +const foo = Bun.file("foo.txt"); // relative to cwd +foo.size; // number of bytes +foo.type; // MIME type +``` + +The reference conforms to the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) interface, so the contents can be read in various formats. + +```ts +const foo = Bun.file("foo.txt"); + +await foo.text(); // contents as a string +await foo.stream(); // contents as ReadableStream +await foo.arrayBuffer(); // contents as ArrayBuffer +``` + +File references can also be created using numerical [file descriptors](https://en.wikipedia.org/wiki/File_descriptor) or `file://` URLs. + +```ts +Bun.file(1234); +Bun.file(new URL(import.meta.url)); // reference to the current file +``` + +A `BunFile` can point to a location on disk where a file does not exist. + +```ts +const notreal = Bun.file("notreal.txt"); +notreal.size; // 0 +notreal.type; // "text/plain;charset=utf-8" +``` + +The default MIME type is `text/plain;charset=utf-8`, but it can be overridden by passing a second argument to `Bun.file`. + +```ts +const notreal = Bun.file("notreal.json", { type: "application/json" }); +notreal.type; // => "text/plain;charset=utf-8" +``` + +For convenience, Bun exposes `stdin`, `stdout` and `stderr` as instances of `BunFile`. + +```ts +Bun.stdin; // readonly +Bun.stdout; +Bun.stderr; +``` + +## Writing files + +`Bun.write(destination, data): Promise<number>` + +The `Bun.write` function is a multi-tool for writing payloads of all kinds to disk. + +The first argument is the `destination` which can have any of the following types: + +- `string`: A path to a location on the file system. Use the `"path"` module to manipulate paths. +- `URL`: A `file://` descriptor. +- `BunFile`: A file reference. + +The second argument is the data to be written. It can be any of the following: + +- `string` +- `Blob` (including `BunFile`) +- `ArrayBuffer` or `SharedArrayBuffer` +- `TypedArray` (`Uint8Array`, et. al.) +- `Response` + +All possible permutations are handled using the fastest available system calls on the current platform. + +{% details summary="See syscalls" %} + +{% table %} + +- Output +- Input +- System call +- Platform + +--- + +- file +- file +- copy_file_range +- Linux + +--- + +- file +- pipe +- sendfile +- Linux + +--- + +- pipe +- pipe +- splice +- Linux + +--- + +- terminal +- file +- sendfile +- Linux + +--- + +- terminal +- terminal +- sendfile +- Linux + +--- + +- socket +- file or pipe +- sendfile (if http, not https) +- Linux + +--- + +- file (doesn't exist) +- file (path) +- clonefile +- macOS + +--- + +- file (exists) +- file +- fcopyfile +- macOS + +--- + +- file +- Blob or string +- write +- macOS + +--- + +- file +- Blob or string +- write +- Linux + +{% /table %} + +{% /details %} + +To write a string to disk: + +```ts +const data = `It was the best of times, it was the worst of times.`; +await Bun.write("output.txt", data); +``` + +To copy a file to another location on disk: + +```js +const input = Bun.file("input.txt"); +const output = Bun.file("output.txt"); // doesn't exist yet! +await Bun.write(output, input); +``` + +To write a byte array to disk: + +```ts +const encoder = new TextEncoder(); +const data = encoder.encode("datadatadata"); // Uint8Array +await Bun.write("output.txt", data); +``` + +To write a file to `stdout`: + +```ts +const input = Bun.file("input.txt"); +await Bun.write(Bun.stdout, input); +``` + +To write an HTTP response to disk: + +```ts +const response = await fetch("https://bun.sh"); +await Bun.write("index.html", response); +``` + +## Benchmarks + +The following is a 3-line implementation of the Linux `cat` command. + +```ts#cat.ts +// 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)); +``` + +To run the file: + +```bash +$ bun ./cat.ts ./path-to-file +``` + +It runs 2x faster than GNU `cat` for large files on Linux. + +{% image src="/images/cat.jpg" /%} + +## Reference + +```ts +interface Bun { + stdin: BunFile; + stdout: BunFile; + stderr: BunFile; + + file(path: string | number | URL, options?: { type?: string }): BunFile; + + write( + destination: string | number | FileBlob | URL, + input: + | string + | Blob + | ArrayBuffer + | SharedArrayBuffer + | TypedArray + | Response, + ): Promise<number>; +} + +interface BunFile { + readonly size: number; + readonly type: string; + + text(): Promise<string>; + stream(): Promise<ReadableStream>; + arrayBuffer(): Promise<ArrayBuffer>; + json(): Promise<any>; +} +``` |