Skip to main content

Mojo struct

FileHandle

struct FileHandle

File handle to an opened file.

Fields

  • handle (Int): The underlying file descriptor (Unix fd).

Implemented traits

AnyType, Defaultable, Movable, UnknownDestructibility, Writer

comptime members

__del__is_trivial

comptime __del__is_trivial = False

__moveinit__is_trivial

comptime __moveinit__is_trivial = True

Methods

__init__

__init__(out self)

Default constructor.

__init__(out self, path: StringSlice[origin], mode: StringSlice[origin])

Construct the FileHandle using the file path and mode.

Args:

  • path (StringSlice): The file path.
  • mode (StringSlice): The mode to open the file in: {"r", "w", "rw", "a"}.

Raises:

If file open mode is not one of the supported modes. If there is an error when opening the file.

__del__

__del__(deinit self)

Closes the file handle.

close

close(mut self)

Closes the file handle.

Raises:

If the operation fails.

read

read(self, size: Int = -1) -> String

Reads data from a file and sets the file handle seek position. If size is left as the default of -1, it will read to the end of the file. Setting size to a number larger than what's in the file will set the String length to the total number of bytes, and read all the data.

Examples:

Read the entire file into a String:

var file = open("/tmp/example.txt", "r")
var string = file.read()
print(string)

Read the first 8 bytes, skip 2 bytes, and then read the next 8 bytes:

import os
var file = open("/tmp/example.txt", "r")
var word1 = file.read(8)
print(word1)
_ = file.seek(2, os.SEEK_CUR)
var word2 = file.read(8)
print(word2)

Read the last 8 bytes in the file, then the first 8 bytes

_ = file.seek(-8, os.SEEK_END)
var last_word = file.read(8)
print(last_word)
_ = file.seek(8, os.SEEK_SET) # os.SEEK_SET is the default start of file
var first_word = file.read(8)
print(first_word)

Args:

  • size (Int): Requested number of bytes to read (Default: -1 = EOF).

Returns:

String: The contents of the file.

Raises:

An error if this file handle is invalid, or if the file read returned a failure.

read[dtype: DType, origin: MutOrigin](self, buffer: Span[Scalar[dtype], origin]) -> Int

Read data from the file into the Span.

This will read n bytes from the file into the input Span where 0 <= n <= len(buffer).

0 is returned when the file is at EOF, or a 0-sized buffer is passed in.

Examples:

import os
from sys.info import size_of

comptime file_name = "/tmp/example.txt"
var file = open(file_name, "r")

# Allocate and load 8 elements
var buffer = InlineArray[Float32, size=8](fill=0)
var bytes = file.read(buffer)
print("bytes read", bytes)

var first_element = buffer[0]
print(first_element)

# Skip 2 elements
_ = file.seek(2 * size_of[DType.float32](), os.SEEK_CUR)

# Allocate and load 8 more elements from file handle seek position
var buffer2 = InlineArray[Float32, size=8](fill=0)
var bytes2 = file.read(buffer2)

var eleventh_element = buffer2[0]
var twelvth_element = buffer2[1]
print(eleventh_element, twelvth_element)

Parameters:

  • dtype (DType): The type that the data will be represented as.
  • origin (MutOrigin): The origin of the passed in Span.

Args:

  • buffer (Span): The mutable Span to read data into.

Returns:

Int: The total amount of data that was read in bytes.

Raises:

An error if this file handle is invalid, or if the file read returned a failure.

read_bytes

read_bytes(self, size: Int = -1) -> List[UInt8]

Reads data from a file and sets the file handle seek position. If size is left as default of -1, it will read to the end of the file. Setting size to a number larger than what's in the file will be handled and set the List length to the total number of bytes in the file.

Examples:

Reading the entire file into a List[Int8]:

var file = open("/tmp/example.txt", "r")
var string = file.read_bytes()

Reading the first 8 bytes, skipping 2 bytes, and then reading the next 8 bytes:

import os
var file = open("/tmp/example.txt", "r")
var list1 = file.read(8)
_ = file.seek(2, os.SEEK_CUR)
var list2 = file.read(8)

Reading the last 8 bytes in the file, then the first 8 bytes:

import os
var file = open("/tmp/example.txt", "r")
_ = file.seek(-8, os.SEEK_END)
var last_data = file.read(8)
_ = file.seek(8, os.SEEK_SET) # os.SEEK_SET is the default start of file
var first_data = file.read(8)

Args:

  • size (Int): Requested number of bytes to read (Default: -1 = EOF).

Returns:

List: The contents of the file.

Raises:

An error if this file handle is invalid, or if the file read returned a failure.

seek

seek(self, offset: UInt64, whence: UInt8 = 0) -> UInt64

Seeks to the given offset in the file.

Examples:

Skip 32 bytes from the current read position:

import os
var f = open("/tmp/example.txt", "r")
_ = f.seek(32, os.SEEK_CUR)

Start from 32 bytes from the end of the file:

import os
var f = open("/tmp/example.txt", "r")
_ = f.seek(-32, os.SEEK_END)

Args:

  • offset (UInt64): The byte offset to seek to.
  • whence (UInt8): The reference point for the offset: os.SEEK_SET = 0: start of file (Default). os.SEEK_CUR = 1: current position. os.SEEK_END = 2: end of file.

Returns:

UInt64: The resulting byte offset from the start of the file.

Raises:

An error if this file handle is invalid, or if file seek returned a failure.

write_once

write_once(mut self, bytes: Span[Byte, origin]) -> Int

Attempt to write bytes to the file, returning the number of bytes written.

This is a low-level method that performs a single write syscall. It may write fewer bytes than requested (partial write), which is not an error. Most users should use write_bytes() instead, which handles partial writes automatically.

Notes: Similar to Rust's Write::write(), this method represents one attempt to write data and may not write all bytes. Use write_bytes() for guaranteed complete writes (equivalent to Rust's write_all()).

Examples:

var file = open("/tmp/example.txt", "w")
var data = String("Hello, World!").as_bytes()

# May write fewer bytes than requested
var bytes_written = file.write_once(data)
print("Wrote", bytes_written, "of", len(data), "bytes")

Args:

  • bytes (Span): The byte span to write to this file.

Returns:

Int: The number of bytes actually written. This may be less than len(bytes).

Raises:

If the file handle is invalid or the write syscall fails.

write_all

write_all(mut self, bytes: Span[Byte, origin])

Write all bytes to the file, handling partial writes automatically.

This method guarantees that all bytes are written by looping until complete or an error occurs. This is equivalent to Rust's write_all().

Notes: Unlike write_once(), this method will not return until all bytes are written or an unrecoverable error occurs. Use this method when you need proper error handling for write operations.

Examples:

var file = open("/tmp/example.txt", "w")
var data = String("Hello, World!").as_bytes()

# Writes all bytes, handling partial writes automatically
file.write_all(data)

Args:

  • bytes (Span): The byte span to write to this file.

Raises:

If the file handle is invalid or the write operation fails.

write_bytes

write_bytes(mut self, bytes: Span[Byte, origin])

Write a span of bytes to the file.

This method is required by the Writer trait and handles partial writes automatically by looping until all bytes are written. On write failure, the program will abort. For better error handling, use write_all().

Notes: This method satisfies the Writer trait requirement. On write failure, the program will abort. Use write_all() for proper error handling.

We use abort() instead of raising errors because the Writer trait currently requires write_bytes() to be non-raising. This allows the trait to work with both infallible writers (String) and fallible writers (files). A future improvement would be to make the Writer trait allow raises, enabling proper error handling here.

Examples:

var file = open("/tmp/example.txt", "w")
var data = String("Hello, World!").as_bytes()
file.write_bytes(data)  # Aborts on error - use write_all() instead

Args:

  • bytes (Span): The byte span to write to this file.

write

write[*Ts: Writable](mut self, *args: *Ts)

Write a sequence of Writable arguments to the provided Writer.

Notes: Passing an invalid file handle (e.g., after calling close()) is undefined behavior. In debug builds, this will trigger an assertion.

Parameters:

  • *Ts (Writable): Types of the provided argument sequence.

Args:

  • *args (*Ts): Sequence of arguments to write to this Writer.

__enter__

__enter__(var self) -> Self

The function to call when entering the context.

Returns:

Self: The file handle.

Was this page helpful?