---
title: Filesystem
description: Rust SDK - Filesystem API reference
---

Read, write, list, and manipulate files inside a running sandbox. Obtained via [`sb.fs()`](/sdk/rust/sandbox#sb-fs). Every op dispatches through the same host-guest channel as command execution, so there is no SSH and no network involved. For bulk file movement, prefer a [volume](/sdk/rust/volumes) that gives the guest direct filesystem access. See [Filesystem](/sandboxes/filesystem) for conceptual usage.

<div className="msb-glance">

  <p className="msb-gl"><span className="msb-dot instance"></span>Read<span className="msb-ct">3</span></p>
  <a className="msb-row" href="#fs-read"><span className="msb-rn">fs.read()</span><span className="msb-rg">whole file as bytes</span></a>
  <a className="msb-row" href="#fs-read_to_string"><span className="msb-rn">fs.read_to_string()</span><span className="msb-rg">whole file as UTF-8</span></a>
  <a className="msb-row" href="#fs-read_stream"><span className="msb-rn">fs.read_stream()</span><span className="msb-rg">stream chunks in</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Write<span className="msb-ct">2</span></p>
  <a className="msb-row" href="#fs-write"><span className="msb-rn">fs.write()</span><span className="msb-rg">overwrite a file</span></a>
  <a className="msb-row" href="#fs-write_stream"><span className="msb-rn">fs.write_stream()</span><span className="msb-rg">stream chunks out</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Directories<span className="msb-ct">3</span></p>
  <a className="msb-row" href="#fs-list"><span className="msb-rn">fs.list()</span><span className="msb-rg">children of a dir</span></a>
  <a className="msb-row" href="#fs-mkdir"><span className="msb-rn">fs.mkdir()</span><span className="msb-rg">create dir + parents</span></a>
  <a className="msb-row" href="#fs-remove_dir"><span className="msb-rn">fs.remove_dir()</span><span className="msb-rg">remove dir recursively</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Files<span className="msb-ct">3</span></p>
  <a className="msb-row" href="#fs-remove"><span className="msb-rn">fs.remove()</span><span className="msb-rg">delete a single file</span></a>
  <a className="msb-row" href="#fs-copy"><span className="msb-rn">fs.copy()</span><span className="msb-rg">copy within sandbox</span></a>
  <a className="msb-row" href="#fs-rename"><span className="msb-rn">fs.rename()</span><span className="msb-rg">rename / move</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Metadata<span className="msb-ct">6</span></p>
  <a className="msb-row" href="#fs-stat"><span className="msb-rn">fs.stat()</span><span className="msb-rg">file metadata</span></a>
  <a className="msb-row" href="#fs-stat_with_follow"><span className="msb-rn">fs.stat_with_follow()</span><span className="msb-rg">stat, control symlinks</span></a>
  <a className="msb-row" href="#fs-set_stat"><span className="msb-rn">fs.set_stat()</span><span className="msb-rg">update metadata</span></a>
  <a className="msb-row" href="#fs-read_link"><span className="msb-rn">fs.read_link()</span><span className="msb-rg">resolve a symlink</span></a>
  <a className="msb-row" href="#fs-symlink"><span className="msb-rn">fs.symlink()</span><span className="msb-rg">create a symlink</span></a>
  <a className="msb-row" href="#fs-exists"><span className="msb-rn">fs.exists()</span><span className="msb-rg">does a path exist</span></a>

  <p className="msb-gl"><span className="msb-dot instance"></span>Host transfer<span className="msb-ct">2</span></p>
  <a className="msb-row" href="#fs-copy_from_host"><span className="msb-rn">fs.copy_from_host()</span><span className="msb-rg">host file -&gt; guest</span></a>
  <a className="msb-row" href="#fs-copy_to_host"><span className="msb-rn">fs.copy_to_host()</span><span className="msb-rg">guest file -&gt; host</span></a>

  <p className="msb-gl"><span className="msb-dot type"></span>Types</p>
  <div className="msb-chiprow">
    <a className="msb-typepill" href="#sandboxfs">SandboxFs</a>
    <a className="msb-typepill" href="#fsentry">FsEntry</a>
    <a className="msb-typepill" href="#fsentrykind">FsEntryKind</a>
    <a className="msb-typepill" href="#fsmetadata">FsMetadata</a>
    <a className="msb-typepill" href="#fssetattrs">FsSetAttrs</a>
    <a className="msb-typepill" href="#fsreadstream">FsReadStream</a>
    <a className="msb-typepill" href="#fswritesink">FsWriteSink</a>
    <a className="msb-typepill" href="#fshandle">FsHandle</a>
  </div>

</div>

<p className="msb-label" id="typical-flow">Typical flow</p>

```rust
use microsandbox::Sandbox;

let sb = Sandbox::builder("api").image("python").create().await?;
let fs = sb.fs();

fs.write("/tmp/config.json", r#"{"debug": true}"#).await?;
let text = fs.read_to_string("/tmp/config.json").await?;
println!("{text}");

for entry in fs.list("/tmp").await? {
    println!("{} ({} bytes)", entry.path, entry.size);
}
```

`sb.fs()` is synchronous and just borrows the sandbox's backend and name; the work happens on the `await`ed methods below, every one of which is `async`.

## Read operations

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn read(&self, path: &str) -> MicrosandboxResult<Bytes>
```

Read an entire file from the guest filesystem into memory as raw bytes.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest, e.g. <code>"/app/config.json"</code>.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">Bytes</span></div>
    <div className="msb-param-desc">File contents as raw bytes.</div>
  </div>
</div>

<Accordion title="Example">

```rust
let bytes = sb.fs().read("/app/logo.png").await?;
println!("{} bytes", bytes.len());
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read_to_string()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn read_to_string(&self, path: &str) -> MicrosandboxResult<String>
```

Read an entire file and decode it as UTF-8. Errors if the contents are not valid UTF-8.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">String</span></div>
    <div className="msb-param-desc">File contents as a UTF-8 string.</div>
  </div>
</div>

<Accordion title="Example">

```rust
let text = sb.fs().read_to_string("/etc/hostname").await?;
println!("{}", text.trim());
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read_stream()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn read_stream(&self, path: &str) -> MicrosandboxResult<FsReadStream>
```

Open a streaming reader that yields chunks of file data as they arrive. Use this for files too large to hold in memory, or to process data incrementally.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsreadstream">FsReadStream</a></div>
    <div className="msb-param-desc">Reader that yields chunks until the file is exhausted.</div>
  </div>
</div>

<Accordion title="Example">

```rust
let mut stream = sb.fs().read_stream("/var/log/big.log").await?;
let mut total = 0;
while let Some(chunk) = stream.recv().await? {
    total += chunk.len();
}
println!("read {total} bytes");
```

</Accordion>

---

## Write operations

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">write()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn write(&self, path: &str, data: impl AsRef<[u8]>) -> MicrosandboxResult<()>
```

Write data to a file in the guest, creating it if it doesn't exist and truncating it if it does. Parent directories must already exist.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>data</code><span className="msb-type">impl AsRef&lt;[u8]&gt;</span></div>
    <div className="msb-param-desc">File content (bytes or a string).</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().write("/tmp/hello.txt", "hi there").await?;
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">write_stream()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn write_stream(&self, path: &str) -> MicrosandboxResult<FsWriteSink>
```

Open a streaming writer for large files. Write chunks incrementally, then call [`FsWriteSink::close()`](#fswritesink) to flush and finalize. The file is created if missing and truncated if it exists.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fswritesink">FsWriteSink</a></div>
    <div className="msb-param-desc">Writer for sending chunks; must be closed to finalize.</div>
  </div>
</div>

<Accordion title="Example">

```rust
let sink = sb.fs().write_stream("/tmp/out.bin").await?;
sink.write(&[0u8; 4096]).await?;
sink.write(&[1u8; 4096]).await?;
sink.close().await?;
```

</Accordion>

---

## Directory operations

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">list()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn list(&self, path: &str) -> MicrosandboxResult<Vec<FsEntry>>
```

List the immediate children of a directory (non-recursive). Each entry carries its path, kind, size, mode, and modification time.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsentry">Vec&lt;FsEntry&gt;</a></div>
    <div className="msb-param-desc">Directory entries.</div>
  </div>
</div>

<Accordion title="Example">

```rust
for entry in sb.fs().list("/app").await? {
    println!("{:?} {}", entry.kind, entry.path);
}
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">mkdir()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn mkdir(&self, path: &str) -> MicrosandboxResult<()>
```

Create a directory, including any missing parent directories.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().mkdir("/app/data/cache").await?;
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">remove_dir()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn remove_dir(&self, path: &str) -> MicrosandboxResult<()>
```

Remove a directory and everything under it, recursively. For a single file use [`remove()`](#fs-remove).

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute directory path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().remove_dir("/app/data/cache").await?;
```

</Accordion>

---

## File operations

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">remove()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn remove(&self, path: &str) -> MicrosandboxResult<()>
```

Delete a single file. Use [`remove_dir()`](#fs-remove_dir) for directories.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute file path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().remove("/tmp/hello.txt").await?;
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn copy(&self, from: &str, to: &str) -> MicrosandboxResult<()>
```

Copy a file from one path to another within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>from</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Source path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>to</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Destination path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().copy("/app/config.json", "/app/config.bak.json").await?;
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">rename()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn rename(&self, from: &str, to: &str) -> MicrosandboxResult<()>
```

Rename or move a file or directory within the sandbox.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>from</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Current path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>to</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">New path inside the guest.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().rename("/tmp/draft.txt", "/tmp/final.txt").await?;
```

</Accordion>

---

## Metadata

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">stat()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn stat(&self, path: &str) -> MicrosandboxResult<FsMetadata>
```

Get metadata for a file or directory: kind, size, mode, read-only flag, and timestamps. A final symlink is followed (equivalent to `stat_with_follow(path, true)`); use [`stat_with_follow()`](#fs-stat_with_follow) to control that.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsmetadata">FsMetadata</a></div>
    <div className="msb-param-desc">File metadata.</div>
  </div>
</div>

<Accordion title="Example">

```rust
let meta = sb.fs().stat("/app/config.json").await?;
println!("{} bytes, mode {:o}", meta.size, meta.mode);
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">stat_with_follow()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn stat_with_follow(&self, path: &str, follow_symlink: bool) -> MicrosandboxResult<FsMetadata>
```

Get metadata, choosing whether to follow a final symlink. With `follow_symlink = false` you stat the link itself rather than its target. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>follow_symlink</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>false</code>, stat the symlink itself instead of its target.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#fsmetadata">FsMetadata</a></div>
    <div className="msb-param-desc">File metadata.</div>
  </div>
</div>

<Accordion title="Example">

```rust
let link_meta = sb.fs().stat_with_follow("/app/current", false).await?;
println!("{:?}", link_meta.kind);
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">set_stat()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn set_stat(&self, path: &str, follow_symlink: bool, attrs: FsSetAttrs) -> MicrosandboxResult<()>
```

Update metadata on a file or directory: mode, owner uid/gid, size, and access/modification times. Only the fields you set on [`FsSetAttrs`](#fssetattrs) are applied. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>follow_symlink</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>false</code>, target the symlink itself instead of its target.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>attrs</code><a className="msb-type" href="#fssetattrs">FsSetAttrs</a></div>
    <div className="msb-param-desc">Attributes to change; unset fields are left untouched.</div>
  </div>
</div>

<Accordion title="Example">

```rust
use microsandbox::sandbox::FsSetAttrs;

sb.fs().set_stat("/app/run.sh", true, FsSetAttrs {
    mode: Some(0o755),
    ..Default::default()
}).await?;
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">read_link()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn read_link(&self, path: &str) -> MicrosandboxResult<String>
```

Read the target of a symbolic link, returning the literal target text. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path of the symlink inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">String</span></div>
    <div className="msb-param-desc">The link's target path.</div>
  </div>
</div>

<Accordion title="Example">

```rust
let target = sb.fs().read_link("/app/current").await?;
println!("-> {target}");
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">symlink()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn symlink(&self, target: &str, link_path: &str) -> MicrosandboxResult<()>
```

Create a symbolic link at `link_path` that points to `target`. Local backend only; cloud returns `Unsupported`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>target</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">What the link points to (literal target text).</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>link_path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path of the symlink to create.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().symlink("/app/releases/v2", "/app/current").await?;
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">exists()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn exists(&self, path: &str) -> MicrosandboxResult<bool>
```

Check whether a file or directory exists at the given path in the guest. Implemented as a `stat()` probe: a successful stat yields `true`, a filesystem-op error yields `false`, and transport errors still propagate.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Absolute path inside the guest.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">bool</span></div>
    <div className="msb-param-desc"><code>true</code> if the path exists.</div>
  </div>
</div>

<Accordion title="Example">

```rust
if sb.fs().exists("/app/config.json").await? {
    println!("config present");
}
```

</Accordion>

---

## Host transfer

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy_from_host()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn copy_from_host(&self, host_path: impl AsRef<Path>, guest_path: &str) -> MicrosandboxResult<()>
```

Copy a file from the host machine into the sandbox, streaming it in chunks. For transferring many files, consider a [bind-mounted volume](/sdk/rust/volumes) instead.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>host_path</code><span className="msb-type">impl AsRef&lt;Path&gt;</span></div>
    <div className="msb-param-desc">Path on the host filesystem.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>guest_path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Destination path inside the sandbox.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().copy_from_host("./local/model.bin", "/app/model.bin").await?;
```

</Accordion>

---

#### <span className="msb-recv">fs.</span><span className="msb-hn">copy_to_host()</span>
<div className="msb-tags"><span className="msb-tag is-instance">instance</span><span className="msb-tag is-async">async</span></div>

```rust
async fn copy_to_host(&self, guest_path: &str, host_path: impl AsRef<Path>) -> MicrosandboxResult<()>
```

Copy a file from the sandbox to the host machine.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>guest_path</code><span className="msb-type">&amp;str</span></div>
    <div className="msb-param-desc">Path inside the sandbox.</div>
  </div>
  <div className="msb-param">
    <div className="msb-param-key"><code>host_path</code><span className="msb-type">impl AsRef&lt;Path&gt;</span></div>
    <div className="msb-param-desc">Destination path on the host.</div>
  </div>
</div>

<Accordion title="Example">

```rust
sb.fs().copy_to_host("/app/out/report.pdf", "./report.pdf").await?;
```

</Accordion>

---

## Types

### SandboxFs

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Returned by <a href="/sdk/rust/sandbox#sb-fs">sb.fs()</a></p>

Filesystem operations handle for a running sandbox, borrowing the parent sandbox's backend and name (it is generic over a lifetime, `SandboxFs<'a>`). Every method dispatches through the same host-guest channel as command execution. Local routes to `core.fs.*` agent messages; cloud returns `Unsupported` per method until cloud guest-fs lands. All operations are listed in the sections above.

`with_backend(backend, name)` is a public constructor for FFI shims that re-assemble a `SandboxFs` per call; most callers obtain one via [`sb.fs()`](/sdk/rust/sandbox#sb-fs).

### FsEntry

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Returned by <a href="#fs-list">list()</a></p>

Metadata for a single entry returned from a directory listing.

| Field | Type | Description |
|-------|------|-------------|
| path | `String` | Path of the entry |
| kind | [`FsEntryKind`](#fsentrykind) | Kind of entry |
| size | `u64` | Size in bytes |
| mode | `u32` | Unix permission bits (e.g. `0o644`) |
| modified | `Option<DateTime<Utc>>` | Last modification time |

### FsEntryKind

<div className="msb-tags"><span className="msb-tag is-type">enum</span></div>

<p className="msb-backref">Used by <a href="#fsentry">FsEntry.kind</a> · <a href="#fsmetadata">FsMetadata.kind</a></p>

The kind of a filesystem entry. Derives `Copy`, `PartialEq`, and `Eq`.

| Variant | Description |
|---------|-------------|
| `File` | Regular file |
| `Directory` | Directory |
| `Symlink` | Symbolic link |
| `Other` | Other entry type (device, socket, etc.) |

### FsMetadata

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Returned by <a href="#fs-stat">stat()</a> · <a href="#fs-stat_with_follow">stat_with_follow()</a></p>

Detailed metadata for a file or directory.

| Field | Type | Description |
|-------|------|-------------|
| kind | [`FsEntryKind`](#fsentrykind) | Kind of entry |
| size | `u64` | Size in bytes |
| mode | `u32` | Unix permission bits |
| readonly | `bool` | Whether the entry is read-only (no owner write bit) |
| modified | `Option<DateTime<Utc>>` | Last modification time |
| created | `Option<DateTime<Utc>>` | Creation time (not populated by guest stat, currently always `None`) |

### FsSetAttrs

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Used by <a href="#fs-set_stat">set_stat()</a></p>

Attributes accepted by `set_stat()`. Re-exported from `microsandbox_protocol::fs`. Derives `Default`, so set only the fields you want to change and spread the rest with `..Default::default()`. Each field is `Option`: `None` leaves that attribute unchanged.

| Field | Type | Description |
|-------|------|-------------|
| mode | `Option<u32>` | Unix permission bits |
| uid | `Option<u32>` | Owner user ID |
| gid | `Option<u32>` | Owner group ID |
| size | `Option<u64>` | File size (truncate or extend) |
| atime | `Option<i64>` | Access time as Unix timestamp seconds |
| mtime | `Option<i64>` | Modification time as Unix timestamp seconds |

### FsReadStream

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Returned by <a href="#fs-read_stream">read_stream()</a></p>

Streaming reader for file data from the sandbox. Obtained via [`read_stream()`](#fs-read_stream).

| Method | Signature | Description |
|--------|-----------|-------------|
| recv() | `recv(&mut self) -> MicrosandboxResult<Option<Bytes>>` | Receive the next chunk; `None` once the file is fully read. Errors if the guest reports a failure. |
| collect() | `collect(self) -> MicrosandboxResult<Bytes>` | Consume the stream and collect all remaining chunks into a single buffer. |

### FsWriteSink

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Returned by <a href="#fs-write_stream">write_stream()</a></p>

Streaming writer for file data to the sandbox. Obtained via [`write_stream()`](#fs-write_stream).

| Method | Signature | Description |
|--------|-----------|-------------|
| write() | `write(&self, data: impl AsRef<[u8]>) -> MicrosandboxResult<()>` | Write a chunk of data. |
| close() | `close(self) -> MicrosandboxResult<()>` | Send EOF and wait for confirmation. Must be called to finalize the write; errors if the guest reports a write failure. |

### FsHandle

<div className="msb-tags"><span className="msb-tag is-type">type</span></div>

Type alias for an agentd-side filesystem handle. Internal plumbing: no public method takes or returns it, and the streaming types hold one only behind their own state.

```rust
pub type FsHandle = u64;
```
