<!-- BusyBot node reference — https://busybot.net/tools/read-write-file/ -->

> Node: Read/Write Files from Disk (`read_write_file`) · Action (binary) · v1
> Category: Core Nodes · Credentials: none
> Updated: 2026-08-16

# Read/Write Files from Disk

> Read or write files on the local filesystem

## Overview

The Read/Write File tool provides two operations: (1) read — reads one or more files from the execution files directory using a path or glob pattern, producing one output item per matched file with binary data and metadata; (2) write — writes binary data from a workflow item to a specified file path within the execution files directory, with optional append mode. All filesystem operations are sandboxed to the execution-scoped directory to prevent directory traversal attacks.

**Category:** Core Nodes  
**Tool Name:** `read_write_file`  
**Version:** 1

**Appearance:** Icon: `lucide-File` | Color: `#6b7280`

## Node Type

**Action (Binary)** — handles file/binary data operations

## Input / Output

| Direction | Port(s) |
|-----------|--------|
| Input | `Input` |
| Output | `Output`, `Error` |

## Credentials

This tool does not require any credentials.

### Operations

| Operation | Value | Description |
|-----------|-------|-------------|
| Read File(s) From Disk | `read` | Read one or more files from the local filesystem |
| Write File to Disk | `write` | Write binary data to a file on the local filesystem |

### Parameters

#### Read File(s) From Disk (`read`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| File(s) Selector | `string` | Yes | — | Specify a file path or glob pattern to read one or more files. Use forward slashes even on Windows. Paths are relative to the execution files directory. Supports expressions like {{ $json.path }}. |
| Options (`options`) | `collection` | No | `{}` | Overrides applied to the metadata of every file this node reads. |
| — File Extension | `string` | No | — | Override the file extension in the output binary metadata. |
| — File Name | `string` | No | — | Override the file name in the output binary metadata. |
| — Mime Type | `string` | No | — | Override the MIME type in the output binary metadata. |
| — Put Output File in Field | `string` | No | `data` | Name of the binary property to store the file in. Default is 'data'. |

#### Write File to Disk (`write`)

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| File Path and Name | `string` | Yes | — | Path and name of the file to write, relative to the execution files directory. Include the file extension. Supports expressions like {{ $json.fileName }}. |
| Input Binary Field | `string` | Yes | `data` | The name of the input binary field containing the file to be written. Names are case-sensitive. |
| Options (`writeOptions`) | `collection` | No | `{}` | Extra write settings. |
| — Append | `boolean` | No | `false` | Whether to append to an existing file instead of overwriting it. Commonly used with text files. |

#### All Operations

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Max Concurrency | `number` | No | `10` | Maximum number of items to process concurrently. |

## Output Data

**Read** changes item cardinality: each input item produces **one output item per matched file**, so one item and a pattern matching eight files gives eight output items. Matching nothing is an error, not an empty result — the message names the selector you used.

Each output item's JSON is the file's metadata; the input item's own JSON is not carried over.

```json
{
  "mimeType": "text/csv",
  "fileType": "text",
  "fileName": "orders.csv",
  "fileExtension": "csv",
  "fileSize": "42.10 kB"
}
```

- `mimeType`, `fileName` and `fileExtension` are detected from the file, unless the matching override in Options replaces them. The File Name and Mime Type overrides also apply to the attached binary data; the File Extension override changes this JSON field only.
- `fileType` is the broad category from the MIME type (`image`, `audio`, `video`, `text` or `application`), or `unknown`.
- `fileSize` is a **human-readable string** such as `938 B`, `42.10 kB` or `2.31 MB`, not a number.

The file contents are attached as binary data under the name given by **Put Output File in Field** (`data` by default), merged with any binary the input item carried.

**Write** is one output item per input item. The input item JSON passes through with one field added:

- `fileName` — the path you asked to write, exactly as supplied.

The written file is attached back to the item as binary data under the same name as **Input Binary Field**, carrying its `fileName`, `mimeType` and `fileSize` in bytes, merged with the item's existing binary.

Reference the result downstream by expression, e.g. `{{ $json.fileName }}`.

## Usage Examples

- Read all CSV files from a directory
- Write a generated PDF to disk
- Read a single image file into binary data
- Save an email attachment to the filesystem
- Read files matching a glob pattern like \*.xlsx

## Example Configuration

Read a single file:

```json
{
  "type": "read_write_file",
  "parameters": {
    "operation": "read",
    "fileSelector": "documents/report.txt",
    "maxConcurrency": 5
  }
}
```

Read every log file, overriding the MIME type and the binary field name:

```json
{
  "type": "read_write_file",
  "parameters": {
    "operation": "read",
    "fileSelector": "logs/*.log",
    "options": {
      "mimeType": "text/plain",
      "dataPropertyName": "logContent"
    },
    "maxConcurrency": 10
  }
}
```

Read files with more than one extension:

```json
{
  "type": "read_write_file",
  "parameters": {
    "operation": "read",
    "fileSelector": "data/*.{json,csv}"
  }
}
```

Write a new file:

```json
{
  "type": "read_write_file",
  "parameters": {
    "operation": "write",
    "fileName": "output/result.json",
    "dataPropertyName": "jsonData",
    "maxConcurrency": 1
  }
}
```

Append to an existing file:

```json
{
  "type": "read_write_file",
  "parameters": {
    "operation": "write",
    "fileName": "logs/application.log",
    "dataPropertyName": "logEntry",
    "writeOptions": {
      "append": true
    },
    "maxConcurrency": 1
  }
}
```

Write a report per item, using an expression in the path:

```json
{
  "type": "read_write_file",
  "parameters": {
    "operation": "write",
    "fileName": "reports/{{ $json.date }}.html",
    "dataPropertyName": "htmlContent",
    "writeOptions": {
      "append": false
    }
  }
}
```

### Error Handling

| Mode | Behavior |
|------|----------|
| **stop** | Halts workflow on first error |
| **continue** | Skips failed items, passes successful ones through |
| **errorPort** | Routes failed items to Error output port |

## Tips

Read files from disk into binary data or write binary data to disk files, sandboxed to the execution files directory.

### Behavior notes

- **Paths are relative and sandboxed.** Everything is resolved inside this execution's own files directory. Absolute paths and `..` segments are rejected, and a file matched outside the directory is skipped. You can only read what a node in the same run has written.
- **Always use forward slashes** in File(s) Selector and File Path and Name, on every platform.
- **Reading nothing is an error.** Unlike a glob that quietly returns an empty list, this node fails the item when the selector matches no files, so a wrong path surfaces immediately.
- **Parent directories are created on write.** `exports/2026/data.csv` works without a separate step.
- **Give each item its own path when writing in parallel.** A fixed File Path and Name with several items means each write overwrites the last. Use an expression in the path, or set Append with Max Concurrency `1` when you deliberately want one accumulating file.
- **The Options overrides only relabel the file.** File Name, File Extension and Mime Type change the metadata reported for the file; they do not convert its contents.