> ## Documentation Index
> Fetch the complete documentation index at: https://docs.opencomputer.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with Files

> Read, write, and manage files inside a sandbox

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { Sandbox } from "@opencomputer/sdk";

  const sandbox = await Sandbox.create();

  await sandbox.files.write("/app/hello.txt", "Hello, World!");
  const content = await sandbox.files.read("/app/hello.txt");
  console.log(content); // "Hello, World!"

  await sandbox.kill();
  ```

  ```python Python theme={null}
  from opencomputer import Sandbox

  async with await Sandbox.create() as sandbox:
      await sandbox.files.write("/app/hello.txt", "Hello, World!")
      content = await sandbox.files.read("/app/hello.txt")
      print(content)  # "Hello, World!"
  ```
</CodeGroup>

## Reading Files

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Read as string
  const text = await sandbox.files.read("/app/config.json");

  // Read as bytes
  const bytes = await sandbox.files.readBytes("/app/image.png");
  ```

  ```python Python theme={null}
  # Read as string
  text = await sandbox.files.read("/app/config.json")

  # Read as bytes
  data = await sandbox.files.read_bytes("/app/image.png")
  ```
</CodeGroup>

## Writing Files

Content can be a string or binary data:

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Write text
  await sandbox.files.write("/app/config.json", JSON.stringify({ port: 3000 }));

  // Write binary
  const imageData = new Uint8Array([...]);
  await sandbox.files.write("/app/logo.png", imageData);
  ```

  ```python Python theme={null}
  # Write text
  await sandbox.files.write("/app/config.json", '{"port": 3000}')

  # Write binary
  await sandbox.files.write("/app/logo.png", image_bytes)
  ```
</CodeGroup>

## Listing Directories

<CodeGroup>
  ```typescript TypeScript theme={null}
  const entries = await sandbox.files.list("/app");
  for (const entry of entries) {
    console.log(entry.isDir ? "📁" : "📄", entry.name, entry.size);
  }
  ```

  ```python Python theme={null}
  entries = await sandbox.files.list("/app")
  for entry in entries:
      kind = "dir" if entry.is_dir else "file"
      print(f"{kind}: {entry.name} ({entry.size} bytes)")
  ```
</CodeGroup>

### EntryInfo

| Field         | TypeScript | Python   | Type    |
| ------------- | ---------- | -------- | ------- |
| Name          | `name`     | `name`   | string  |
| Is directory  | `isDir`    | `is_dir` | boolean |
| Full path     | `path`     | `path`   | string  |
| Size in bytes | `size`     | `size`   | number  |

## Managing Files

### Create Directory

<CodeGroup>
  ```typescript TypeScript theme={null}
  await sandbox.files.makeDir("/app/data");
  ```

  ```python Python theme={null}
  await sandbox.files.make_dir("/app/data")
  ```
</CodeGroup>

### Remove

Deletes a file or directory:

<CodeGroup>
  ```typescript TypeScript theme={null}
  await sandbox.files.remove("/app/temp");
  ```

  ```python Python theme={null}
  await sandbox.files.remove("/app/temp")
  ```
</CodeGroup>

### Check Existence

<CodeGroup>
  ```typescript TypeScript theme={null}
  if (await sandbox.files.exists("/app/config.json")) {
    const config = await sandbox.files.read("/app/config.json");
  }
  ```

  ```python Python theme={null}
  if await sandbox.files.exists("/app/config.json"):
      config = await sandbox.files.read("/app/config.json")
  ```
</CodeGroup>

<Note>
  `exists()` is a client-side convenience — it attempts a file read and returns `false` on error. There is no dedicated HTTP endpoint for existence checks.
</Note>

## Large Files

All file operations are streamed end-to-end using 256KB chunks — there is no file size limit beyond available disk space. Files up to 200MB+ transfer reliably at \~20 MB/s.

The standard `read()`, `readBytes()`, and `write()` methods work for large files, but they buffer the full content in memory on the client side. For very large files, use the streaming methods to avoid high memory usage:

<CodeGroup>
  ```typescript TypeScript theme={null}
  // Stream a large file download — returns a ReadableStream, not a buffer
  const stream = await sandbox.files.readStream("/data/model.bin");

  // Pipe to a file, or process chunks incrementally
  const reader = stream.getReader();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    // process each Uint8Array chunk...
  }

  // Stream a large file upload — accepts ReadableStream or Uint8Array
  const fileStream = someReadableStream; // e.g. from fs.createReadStream
  await sandbox.files.writeStream("/data/model.bin", fileStream);

  // Uint8Array also works (sent without buffering a copy)
  await sandbox.files.writeStream("/data/output.bin", largeUint8Array);
  ```

  ```python Python theme={null}
  # Stream a large file download — returns an async byte iterator
  stream = await sandbox.files.read_stream("/data/model.bin")
  async for chunk in stream:
      # process each bytes chunk...
      pass

  # Stream a large file upload — accepts an async iterator
  async def file_chunks():
      with open("local_model.bin", "rb") as f:
          while chunk := f.read(256 * 1024):
              yield chunk

  await sandbox.files.write_stream("/data/model.bin", file_chunks())
  ```
</CodeGroup>

## Examples

### Upload and Run a Script

<CodeGroup>
  ```typescript TypeScript theme={null}
  await sandbox.files.write("/tmp/setup.sh", `#!/bin/bash
  apt-get update && apt-get install -y redis-server
  redis-server --daemonize yes
  `);
  await sandbox.exec.run("chmod +x /tmp/setup.sh && /tmp/setup.sh");
  ```

  ```python Python theme={null}
  await sandbox.files.write("/tmp/setup.sh", """#!/bin/bash
  apt-get update && apt-get install -y redis-server
  redis-server --daemonize yes
  """)
  await sandbox.exec.run("chmod +x /tmp/setup.sh && /tmp/setup.sh")
  ```
</CodeGroup>

<Tip>
  Full reference: [TypeScript SDK](/reference/typescript-sdk#filesystem) · [Python SDK](/reference/python-sdk#filesystem) · [HTTP API](/reference/api#filesystem).
</Tip>
