Core

File System and I/O

NAppGUI splits filesystem access into two layers: low-level OS wrappers in osbs/bfile.h and higher-level convenience functions in core/hfile.h. Streams then provide a unified read/write surface across memory, files, and sockets.

Relevant Source Files

Low-Level vs High-Level Filesystem Layers

Layer Main API Role
osbs bfile_*, bfile_dir_* Thin OS-facing file and directory operations.
core hfile_* Higher-level helpers for sync, buffering, string loading, stream creation, and app/home/tmp path resolution.

bfile: Basic Filesystem Access

bfile.h provides the raw path and handle operations: working/home/data/executable/temp directories, directory creation/open/enumeration/delete, file create/open/close, stat calls, read/write, seek, delete, and rename.

This is the layer used when the codebase needs explicit control over file handles or platform path queries without the higher-level object wrappers.

hfile: Higher-Level Convenience API

hfile.h builds on the low-level layer with more application-friendly operations: recursive directory sync, recursive listing, file existence/uptodate checks, whole-file load into Buffer, String, or Stream, writing files from strings or raw data, and directory walking with listeners.

It also exposes application-specific path helpers like hfile_appdata(...), hfile_home_dir(...), and hfile_tmp_path(...), which is why many demos persist state without writing platform-specific path code.

Stream API

Stream is the main I/O abstraction inside the repo. It can be created from a memory block, memory buffer, file, appendable file, or socket. It exposes endian and Unicode format selection, tokenization settings, bytes read/written counters, error state, token positions, and a wide set of typed read/write helpers for integers, reals, booleans, characters, lines, and tokens.

That is why serialization code like DBind, image import/export, JSON parsing, and resource loading can all share one I/O vocabulary.

Typical Usage Pattern

Use bfile when you need explicit low-level filesystem control, hfile when you want whole-file or directory-level convenience, and Stream when the caller should not care whether bytes come from memory, disk, or a socket.

The three layers are intentionally complementary rather than redundant.