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

# File I/O with iodine

> Read about iodine's Linux x86_64 file and stream helpers.

The [`iodine/streamer.ih` library](https://github.com/MaimingyouRnlwkey/Hypotenuse-in-C-Triangle/blob/main/plstd/streamer.plib) provides higher-level helpers for reading files, writing strings, measuring content, copying content to another path, and removing files. It uses [`streamer_x86.ih`](https://github.com/MaimingyouRnlwkey/Hypotenuse-in-C-Triangle/blob/main/plstd/streamer_x86.plib) internally for low-level Linux x86\_64 assembly system calls.

<Note>
  Import `streamer` in your program. The `streamer_x86.ih` file is an assembly backend used by the higher-level library, not the application-facing file API.
</Note>

## Import the library

Import only the functions you need. You can expose each function to call it directly, or use `@lib` to keep library calls explicit.

<Tabs>
  <Tab title="Expose functions">
    ```c theme={null}
    using instream from <iodine/streamer>;
    using sizeget from <iodine/streamer>;
    using printd from <iodine/printd>;
    expose instream;
    expose sizeget;
    expose printd;

    int main() {
        string contents = instream("notes.txt");
        int length = sizeget("notes.txt");
        printd("Read %d characters", length);
        return 0;
    }
    ```
  </Tab>

  <Tab title="Keep calls qualified">
    ```c theme={null}
    using instream from <iodine/streamer>;
    using sizeget from <iodine/streamer>;
    using printd from <iodine/printd>;

    int main() {
        string contents = instream@lib("notes.txt");
        int length = sizeget@lib("notes.txt");
        printd@lib("Read %d characters", length);
        return 0;
    }
    ```
  </Tab>
</Tabs>

## Functions

| Function | Description |
| - | - |
| `instream(path)` | Read a file and return its contents as a string. |
| `outstream(buffer, path)` | Attempt to write a string to a file path and return the input string on its success-shaped path. See the current limitation below. |
| `sizeget(path)` | Read the file and return the length of the returned string. |
| `steal(path, out_path)` | Read a file and attempt to write its contents to another path, returning the contents if the write helper reports success. |
| `remove(path)` | Attempt to remove an existing path. |

The library also defines helpers in the `streams` namespace: `open_file`, `close_file`, `exists`, `remove_file`, `read_file`, and `write_file`. These support the functions above; prefer the top-level functions unless you specifically need a lower-level helper.

The `streamer_x86.ih` backend wraps Linux system calls in the `streams_impl_x86` namespace:

| Wrapper | Linux syscall | Purpose |
| - | - | - |
| `sys_read(fd, buf, count)` | `read` (`0`) | Read bytes from a file descriptor. |
| `sys_write(fd, buf, count)` | `write` (`1`) | Write bytes to a file descriptor. |
| `sys_open(path, flags, mode)` | `open` (`2`) | Open a path with the requested flags and mode. |
| `sys_close(fd)` | `close` (`3`) | Close a file descriptor. |
| `sys_unlink(path)` | `unlink` (`87`) | Remove a path from the filesystem. |

These low-level wrappers return the raw syscall result. They are implementation details; use the top-level library functions for ordinary file operations.

## Read a file

`instream` opens a path, reads in chunks, and returns the contents as a string:

```c theme={null}
using instream from <iodine/streamer>;
using printd from <iodine/printd>;
expose instream;
expose printd;

int main() {
    string contents = instream("notes.txt");
    printd("%s", contents);
    return 0;
}
```

The implementation reads chunks of up to 256 bytes and appends a null terminator. The current error path returns the literal `"stderr: failed to read file"`; callers should not treat that value as file contents.

## Measure file contents

`sizeget` reads the file through `instream` and returns `len()` of the resulting string:

```c theme={null}
using sizeget from <iodine/streamer>;
using printd from <iodine/printd>;
expose sizeget;
expose printd;

int main() {
    int length = sizeget("notes.txt");
    printd("Length: %d", length);
    return 0;
}
```

This measures the length of the returned string, not metadata such as allocated file size. The error string returned by `instream` also means the current implementation does not provide a reliable negative error result through `sizeget`.

## Write, copy, and remove

The API includes `outstream(buffer, path)`, `steal(path, out_path)`, and `remove(path)`. However, the current `open_file` helper opens paths with flags `0` (`O_RDONLY` on Linux), and `outstream` uses that helper before calling `write`. It also does not check the result of the write system call.

<Warning>
  `outstream` and `steal` are not reliable for writing with the current Linux x86\_64 implementation. Do not rely on them to create or update files until the library is fixed. `remove` uses the Linux `unlink` system call for an existing path.
</Warning>

## Source files

| File | Layer |
| - | - |
| [`streamer.ih`](https://github.com/MaimingyouRnlwkey/Hypotenuse-in-C-Triangle/blob/main/plstd/streamer.plib) | Higher-level file and stream helpers |
| [`streamer_x86.ih`](https://github.com/MaimingyouRnlwkey/Hypotenuse-in-C-Triangle/blob/main/plstd/streamer_x86.plib) | Low-level Linux x86\_64 assembly backend used by `streamer.ih` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.