Reading Files in Bnlang
Reading files is one of the most common things a program does.
The built-in io module gives you three flavors, from simplest to most powerful:
io.read_file(path)— synchronous; returns the whole file as a string.io.read_file_async(path, cb)— asynchronous; the callback receives the data when ready.io.open_read(path)— streaming; pull the file in chunks for memory-friendly processing.
Synchronous Read
The simplest form. Blocks the event loop until the whole file is in memory. Use this in scripts and for small files.
import "io" as io;
var text = io.read_file("notes.txt");
print(text);
Asynchronous Read
Returns immediately. The callback is invoked once the read completes — first argument is the error (or null), second is the file contents.
import "io" as io;
io.read_file_async("notes.txt", function (err, data) {
if (err != null) {
print("read failed:", err);
return;
}
print("got", data.byte_length, "bytes");
});
print("scheduled — keep doing other work");
Streaming Large Files
For files that don't fit comfortably in memory, open a read stream and pull chunks. The callback receives chunk = null to signal EOF.
import "io" as io;
var src = io.open_read("big.log");
var total = 0;
function on_chunk(err, chunk) {
if (err != null) { print("read err:", err); src.close(); return; }
if (chunk == null) {
print("done. total:", total, "bytes");
src.close();
return;
}
total = total + chunk.byte_length;
src.read(64 * 1024, on_chunk);
}
src.read(64 * 1024, on_chunk);
Best Practices
- Reach for
io.read_file_asyncby default in long-running programs (servers, daemons). - Use the sync variant for one-shot scripts where simplicity wins.
- For files larger than, say, a few megabytes, prefer
io.open_readso you don't allocate a huge string. - Always call
src.close()when you're done with a stream — otherwise the OS file handle stays open.