docs/sdk/go/filesystem.mdx
Read and write files inside a running sandbox over the same host-guest channel as command execution: no SSH, no network. See Filesystem for usage examples. For bulk file transfer, prefer a volume.
<div className="msb-glance"> <p className="msb-gl"><span className="msb-dot instance"></span>Methods · SandboxFSOps<span className="msb-ct">16</span></p> <a className="msb-row" href="#fs-read"><span className="msb-rn">fs.Read()</span><span className="msb-rg">read a file as bytes</span></a> <a className="msb-row" href="#fs-readstring"><span className="msb-rn">fs.ReadString()</span><span className="msb-rg">read a file as a string</span></a> <a className="msb-row" href="#fs-write"><span className="msb-rn">fs.Write()</span><span className="msb-rg">write bytes</span></a> <a className="msb-row" href="#fs-writestring"><span className="msb-rn">fs.WriteString()</span><span className="msb-rg">write a string</span></a> <a className="msb-row" href="#fs-list"><span className="msb-rn">fs.List()</span><span className="msb-rg">list a directory</span></a> <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-mkdir"><span className="msb-rn">fs.Mkdir()</span><span className="msb-rg">create a directory</span></a> <a className="msb-row" href="#fs-remove"><span className="msb-rn">fs.Remove()</span><span className="msb-rg">delete a file</span></a> <a className="msb-row" href="#fs-removedir"><span className="msb-rn">fs.RemoveDir()</span><span className="msb-rg">delete a directory</span></a> <a className="msb-row" href="#fs-copy"><span className="msb-rn">fs.Copy()</span><span className="msb-rg">copy within the guest</span></a> <a className="msb-row" href="#fs-rename"><span className="msb-rn">fs.Rename()</span><span className="msb-rg">rename / move</span></a> <a className="msb-row" href="#fs-exists"><span className="msb-rn">fs.Exists()</span><span className="msb-rg">test a path</span></a> <a className="msb-row" href="#fs-copyfromhost"><span className="msb-rn">fs.CopyFromHost()</span><span className="msb-rg">host file into guest</span></a> <a className="msb-row" href="#fs-copytohost"><span className="msb-rn">fs.CopyToHost()</span><span className="msb-rg">guest file to host</span></a> <a className="msb-row" href="#fs-readstream"><span className="msb-rn">fs.ReadStream()</span><span className="msb-rg">stream a large read</span></a> <a className="msb-row" href="#fs-writestream"><span className="msb-rn">fs.WriteStream()</span><span className="msb-rg">stream a large write</span></a> <p className="msb-gl"><span className="msb-dot type"></span>Types</p> <div className="msb-chiprow"> <a className="msb-typepill" href="#fsentry">FsEntry</a> <a className="msb-typepill" href="#fsentrykind">FsEntryKind</a> <a className="msb-typepill" href="#fsstat">FsStat</a> <a className="msb-typepill" href="#fsreadstream">FsReadStream</a> <a className="msb-typepill" href="#fswritestream">FsWriteStream</a> </div> </div> <p className="msb-label" id="typical-flow">Typical flow</p>import m "github.com/superradcompany/microsandbox/sdk/go"
fs := sb.FS() // 1. get the accessor
err := fs.WriteString(ctx, "/tmp/config.json", `{"debug":true}`) // 2. write
if err != nil {
return err
}
content, err := fs.ReadString(ctx, "/tmp/config.json") // 3. read back
if err != nil {
return err
}
fmt.Println(content)
The accessor is obtained from a running sandbox via sb.FS(). Every method takes a context.Context first and returns an error (wrapped, inspectable with m.IsKind).
func (fs *SandboxFSOps) Read(ctx context.Context, path string) ([]byte, error)
Read the entire contents of a file as raw bytes. The default FFI buffer is 1 MiB; for files larger than ~750 KiB (after base64 inflation) the runtime returns BufferTooSmall on the single-shot path, and this method transparently falls back to ReadStream so callers get a uniform bytes-returning interface up to runtime memory limits.
data, err := fs.Read(ctx, "/etc/hostname")
if err != nil {
return err
}
fmt.Printf("%d bytes\n", len(data))
func (fs *SandboxFSOps) ReadString(ctx context.Context, path string) (string, error)
Read a file and return its contents as a string. The bytes are reinterpreted as UTF-8 without validation.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the read.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</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.</div> </div> </div> <Accordion title="Example">content, err := fs.ReadString(ctx, "/tmp/config.json")
func (fs *SandboxFSOps) Write(ctx context.Context, path string, data []byte) error
Write bytes to a file, creating it if it does not exist and truncating it if it does.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the write.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</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">[]byte</span></div> <div className="msb-param-desc">Bytes to write.</div> </div> </div> <Accordion title="Example">err := fs.Write(ctx, "/tmp/data.bin", []byte{0x00, 0x01, 0x02})
func (fs *SandboxFSOps) WriteString(ctx context.Context, path, content string) error
Write a UTF-8 string to a file. Convenience wrapper over Write.
err := fs.WriteString(ctx, "/tmp/hello.txt", "hi")
func (fs *SandboxFSOps) List(ctx context.Context, path string) ([]FsEntry, error)
List the entries in a directory inside the sandbox.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the listing.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</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">[]FsEntry</a></div> <div className="msb-param-desc">Directory entries.</div> </div> </div> <Accordion title="Example">entries, err := fs.List(ctx, "/etc")
if err != nil {
return err
}
for _, e := range entries {
fmt.Printf("%s (%s, %d bytes)\n", e.Path, e.Kind, e.Size)
}
func (fs *SandboxFSOps) Stat(ctx context.Context, path string) (*FsStat, error)
Get detailed metadata for a file or directory.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the stat.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</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="#fsstat">*FsStat</a></div> <div className="msb-param-desc">File metadata.</div> </div> </div> <Accordion title="Example">st, err := fs.Stat(ctx, "/etc/hosts")
if err != nil {
return err
}
fmt.Printf("%d bytes, dir=%v\n", st.Size, st.IsDir)
func (fs *SandboxFSOps) Mkdir(ctx context.Context, path string) error
Create a directory and any missing parents inside the sandbox.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the operation.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Absolute directory path inside the guest.</div> </div> </div> <Accordion title="Example">err := fs.Mkdir(ctx, "/app/cache/sessions")
func (fs *SandboxFSOps) Remove(ctx context.Context, path string) error
Delete a single file. Use RemoveDir for directories.
err := fs.Remove(ctx, "/tmp/scratch.txt")
func (fs *SandboxFSOps) RemoveDir(ctx context.Context, path string) error
Remove a directory recursively.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the operation.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Absolute directory path inside the guest.</div> </div> </div> <Accordion title="Example">err := fs.RemoveDir(ctx, "/app/cache")
func (fs *SandboxFSOps) Copy(ctx context.Context, src, dst string) error
Copy a file within the sandbox.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the operation.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>src</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Source path inside the guest.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>dst</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Destination path inside the guest.</div> </div> </div> <Accordion title="Example">err := fs.Copy(ctx, "/etc/hosts", "/tmp/hosts.bak")
func (fs *SandboxFSOps) Rename(ctx context.Context, src, dst string) error
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>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the operation.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>src</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Current path inside the guest.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>dst</code><span className="msb-type">string</span></div> <div className="msb-param-desc">New path inside the guest.</div> </div> </div> <Accordion title="Example">err := fs.Rename(ctx, "/tmp/old.log", "/tmp/archive/old.log")
func (fs *SandboxFSOps) Exists(ctx context.Context, path string) (bool, error)
Report whether a file or directory exists at the given path.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the check.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>path</code><span className="msb-type">string</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">ok, err := fs.Exists(ctx, "/app/.initialized")
if err != nil {
return err
}
if !ok {
// first boot
}
func (fs *SandboxFSOps) CopyFromHost(ctx context.Context, hostPath, guestPath string) error
Copy a file from the host machine into the sandbox. For transferring many files, consider a bind-mounted volume instead.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the copy.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>hostPath</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Source path on the host.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>guestPath</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Destination path inside the guest.</div> </div> </div> <Accordion title="Example">err := fs.CopyFromHost(ctx, "./seed.db", "/app/data/seed.db")
func (fs *SandboxFSOps) CopyToHost(ctx context.Context, guestPath, hostPath string) error
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>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the copy.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>guestPath</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Source path inside the guest.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>hostPath</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Destination path on the host.</div> </div> </div> <Accordion title="Example">err := fs.CopyToHost(ctx, "/app/output/report.csv", "./report.csv")
func (fs *SandboxFSOps) ReadStream(ctx context.Context, path string) (*FsReadStream, error)
Open a streaming reader for a file. Use this for files too large to fit in memory; data is delivered in chunks. The caller must Close the returned *FsReadStream. Read falls back to this automatically when a file exceeds the single-shot buffer.
rs, err := fs.ReadStream(ctx, "/var/log/syslog")
if err != nil {
return err
}
defer rs.Close()
for {
chunk, err := rs.Recv(ctx)
if err != nil {
return err
}
if chunk == nil {
break // EOF
}
os.Stdout.Write(chunk)
}
// Or drain it as an io.WriterTo.
_, err = rs.WriteTo(os.Stdout)
func (fs *SandboxFSOps) WriteStream(ctx context.Context, path string) (*FsWriteStream, error)
Open a streaming writer for a file. Use this for files too large to fit in memory. The caller must call Close(ctx) on the returned *FsWriteStream to finalise the write.
ws, err := fs.WriteStream(ctx, "/tmp/big.bin")
if err != nil {
return err
}
if _, err := ws.Write(largeChunk); err != nil {
return err
}
if err := ws.Close(ctx); err != nil {
return err
}
A single directory listing entry.
| Field | Type | Description |
|---|---|---|
| Path | string | File path |
| Kind | FsEntryKind | Entry type |
| Size | int64 | File size in bytes |
| Mode | uint32 | Unix permission bits |
Classifies a directory listing entry. Defined as type FsEntryKind string.
| Constant | Value | Description |
|---|---|---|
FsEntryKindFile | "file" | Regular file |
FsEntryKindDirectory | "directory" | Directory |
FsEntryKindSymlink | "symlink" | Symbolic link |
FsEntryKindOther | "other" | Other entry type |
Detailed file metadata.
| Field | Type | Description |
|---|---|---|
| Path | string | File path |
| Size | int64 | File size in bytes |
| Mode | uint32 | Unix permission bits |
| ModTime | time.Time | Last modified timestamp; zero value if the guest did not report one |
| IsDir | bool | Whether the path is a directory |
An open streaming read from a guest file. Must be closed with Close when done.
| Method | Returns | Description |
|---|---|---|
Recv(ctx context.Context) | ([]byte, error) | Receive the next chunk; returns (nil, nil) at EOF |
WriteTo(w io.Writer) | (int64, error) | Drain the stream into w using context.Background(); implements io.WriterTo |
CopyTo(ctx context.Context, w io.Writer) | (int64, error) | Drain into w honouring ctx for per-chunk cancellation |
Close() | error | Release the read stream handle |
On a write error or partial write, WriteTo and CopyTo return the partial byte count and leave the stream open so the caller can recover; close it explicitly in either case.
An open streaming write to a guest file. Must be closed with Close(ctx) to finalise the write.
| Method | Returns | Description |
|---|---|---|
Write(p []byte) | (int, error) | Send a chunk; implements io.Writer, uses context.Background() internally |
WriteCtx(ctx context.Context, data []byte) | error | Send a chunk with explicit context control |
Close(ctx context.Context) | error | Send the EOF marker and wait for the guest to confirm; must be called to complete the write |