Ch11.1: File I/O
Overview
fast_io provides high-performance file I/O through several
buffered file types. These wrap the native file handle with user-space
buffering for maximum throughput.
1. File Types
Each buffered file type comes in five character-type variants. The default
uses char; the others are prefixed with u8,
u16, u32, or w (for wchar_t).
| Direction | char |
char8_t |
char16_t |
char32_t |
wchar_t |
|---|---|---|---|---|---|
| Input | ibuf_file |
u8ibuf_file |
u16ibuf_file |
u32ibuf_file |
wibuf_file |
| Output | obuf_file |
u8obuf_file |
u16obuf_file |
u32obuf_file |
wobuf_file |
| Input/Output | iobuf_file |
u8iobuf_file |
u16iobuf_file |
u32iobuf_file |
wiobuf_file |
All file types are RAII-managed: the file is automatically closed when the object goes out of scope.
2. Hello World Example
Here is a complete file I/O example:
#include <fast_io.h>
#include <fast_io_device.h>
int main() {
using namespace ::fast_io::iomnp;
// Write to a file
{
::fast_io::obuf_file obf(u8"hello.txt");
print(obf, "Hello, File I/O!\n"
"Line 2: ", 42, " + ", 100, " = ", 142);
} // file closed automatically here
// Read from the file line by line
{
::fast_io::ibuf_file ibf(u8"hello.txt");
for (::fast_io::string line; scan<true>(ibf, str_line_get(line)); ) {
println(line);
}
}
}
3. Opening Modes
Use ::fast_io::open_mode to control how files are opened.
The most commonly used cross-platform flags are:
| Flag | Description |
|---|---|
open_mode::in |
Open for reading. |
open_mode::out |
Open for writing. |
open_mode::app |
Append mode (writes go to end). |
open_mode::trunc |
Truncate existing file to zero length. |
open_mode::creat |
Create the file if it does not exist. |
open_mode::excl |
Fail if the file already exists (also called noreplace). |
open_mode::direct |
Bypass the OS page cache (POSIX O_DIRECT). |
open_mode::sync |
Synchronous I/O — flush after each write. |
open_mode::no_block |
Non-blocking mode. |
open_mode::text |
Text mode (newline translation). Ignored by native_file, which is always binary. Only meaningful for c_file and filebuf_file. |
open_mode::temporary |
Create a temporary file that is deleted on close. |
There are also platform-specific flags for Windows attributes (e.g.
hidden, archive, compressed,
encrypted) and Linux-specific flags (e.g. no_atime,
path).
Combine flags with |:
// Open for writing, create if not exists, truncate if exists
::fast_io::obuf_file obf(u8"data.bin", ::fast_io::open_mode::out | ::fast_io::open_mode::trunc);
// Open for reading and writing
::fast_io::iobuf_file iof(u8"data.txt", ::fast_io::open_mode::in | ::fast_io::open_mode::out);
4. UTF-8 File I/O
For UTF-8 text files, use the u8 variants. Note that
u8string uses char8_t, which is a different
character type from the char used by standard output. To
print UTF-8 text to the console, use a u8obuf_file wrapping
stdout, or use ::fast_io::mnp::code_cvt to
convert between character types.
#include <fast_io.h>
#include <fast_io_device.h>
#include <fast_io_legacy.h>
int main() {
using namespace ::fast_io::iomnp;
// Write UTF-8 to a file
{
::fast_io::u8obuf_file u8obf("utf8.txt");
print(u8obf, u8"Unicode: 你好世界 🌍\n");
}
// Read UTF-8 file and print to a UTF-8 stdout
{
::fast_io::u8ibuf_file u8ibf("utf8.txt");
::fast_io::u8c_io_observer u8out(stdout);
for (::fast_io::u8string line; scan<true>(u8ibf, str_line_get(line)); ) {
println(u8out, line);
}
}
}
5. Opening Files Relative to a Directory
::fast_io::dir_file opens a directory handle. Use at(df)
to open files relative to that directory — this is safer and more efficient
than building full paths, and avoids race conditions from path resolution.
#include <fast_io.h>
#include <fast_io_device.h>
int main() {
using namespace ::fast_io::iomnp;
// Open a directory
::fast_io::dir_file df(u8"my_directory");
// Open a file relative to that directory
::fast_io::obuf_file obf(at(df), "hello.txt");
print(obf, "Written relative to my_directory\n");
}
The full directory iteration API (current(at(df)),
recursive(at(df)), and directory entry functions) is covered
in the filesystem chapter (Ch11.18).
Key takeaways
ibuf_filefor reading,obuf_filefor writing,iobuf_filefor both.- Each type has five character variants:
char,u8(char8_t),u16(char16_t),u32(char32_t), andw(wchar_t). - Files are RAII-managed — automatically closed on scope exit.
- Use
open_modeflags to control opening behavior. There is noopen_mode::binary— native files are always binary; useopen_mode::textfor text mode (only meaningful forc_fileandfilebuf_file). - Use
using namespace ::fast_io::iomnp;(which includes::fast_io::io) then callprintln/print/scanand manipulators likestr_line_getdirectly. - Use
scanwith thestr_line_getmanipulator for line-by-line reading:for (::fast_io::string line; scan<true>(ibf, str_line_get(line)); ) { ... } - You cannot directly print between different character types. Use
::fast_io::mnp::code_cvtto convert, or write to a device with the matching character type. - Use
::fast_io::dir_fileto open a directory, thenat(df)to open files relative to it. Directory iteration is covered in Ch11.18.