Skip to content

File I/O (std.io)

The std.io module provides basic file input/output operations using the C standard library.

nic
import std.io;

The File Struct

Files are represented as opaque handles wrapping C's FILE*:

nic
pub struct File {
    handle: opaque
}

File Modes

nic
pub enum FileMode {
    Read,       // "r" - Open for reading (file must exist)
    Write,      // "w" - Create/truncate for writing
    Append,     // "a" - Open/create for appending
    ReadWrite   // "r+" - Open for both reading and writing
}

Opening and Closing Files

open

Open a file with the specified mode:

nic
import std.io.file(open, close, FileMode);

let file = open("data.txt", Read);
defer close(file);

// Use file...

close

Close a file and release its resources:

nic
let file = open("output.txt", Write);
// Write to file...
close(file);  // Must be called to flush and release

Writing to Files

write_string

Write a string to a file:

nic
import std.io.file(open, close, write_string, FileMode);

fn save_config(path: string, content: string) -> bool {
    let file = open(path, Write);
    let result = write_string(file, content);
    close(file);
    return result >= 0;
}

// Usage
save_config("config.txt", "key=value\n");

Reading Files

is_eof

Check if the file position is at end-of-file:

nic
import std.io.file(open, close, is_eof, FileMode);

let file = open("data.txt", Read);
defer close(file);

while !is_eof(file) {
    // Read from file...
}

Complete Example

nic
import std.io.file(open, close, write_string, is_eof, FileMode);

fn main() -> i32 {
    // Write a file
    let out = open("hello.txt", Write);
    write_string(out, "Hello, World!\n");
    write_string(out, "This is Nic.\n");
    close(out);

    println("File written successfully");
    return 0;
}

Working with Text Files

Here's a pattern for writing multiple lines:

nic
import std.io.file(open, close, write_string, FileMode);

fn write_lines(path: string, lines: *Vec[*String]) -> unit {
    let file = open(path, Write);
    defer close(file);

    for i in 0..lines.len() {
        match lines.get(i) {
            Some(line) => {
                write_string(file, line.as_str());
                write_string(file, "\n");
            },
            None => {},
        }
    }
}

Appending to Files

nic
import std.io.file(open, close, write_string, FileMode);

fn log_message(path: string, message: string) -> unit {
    let file = open(path, Append);
    write_string(file, message);
    write_string(file, "\n");
    close(file);
}

// Each call appends to the file
log_message("app.log", "Application started");
log_message("app.log", "Processing data...");
log_message("app.log", "Complete");

API Reference

nic
// std.io.file module

/// File handle (opaque pointer to FILE*)
pub struct File {
    handle: opaque
}

/// File open modes
pub enum FileMode {
    Read,       // Open for reading
    Write,      // Create/truncate for writing
    Append,     // Open/create for appending
    ReadWrite   // Open for reading and writing
}

/// Open a file with the specified mode
pub fn open(path: string, mode: FileMode) -> *File;

/// Close a file and release resources
pub fn close(file: *File) -> unit;

/// Write a string to a file
/// Returns number of characters written, or negative on error
pub fn write_string(file: *File, s: string) -> i32;

/// Check if at end of file
pub fn is_eof(file: *File) -> bool;

Notes

  • Always close files when done to ensure data is flushed
  • Use defer close(file) for automatic cleanup
  • The module wraps C standard library functions (fopen, fclose, fputs, feof)
  • File handles are automatically heap-allocated and must be released via close()

See Also

Released under the MIT License.