Let's look at ways to read files in Hare using the `os` and `io` modules.
use bufio;
use io;
use fmt;
use os;
use strings;
export fn main() void = {
// We can try to read an entire files contents into a variable.
// We'll open a file first and then read from the file handle
// into a variable.
const handle = os::open("./reading-files.txt")!;
defer io::close(handle)!;
// We define a buffer to hold the contents of the file using the
// provided OS buffer size.
let overview: [os::BUFSZ]u8 = [0...];
// Next we'll read all the data from the handle and provide the
// slice in which to store the file contents. The number of
// bytes read is returned which we will use later.
const osz = match(io::read(handle, overview[..])) {
// Since we overallocated our buffer we'll read all of the file
// contents and get returned how many bytes we read so we'll
// match on that case and yield that size back up.
case let sz: size =>
yield sz;
// There could potentially be an end of file error while we
// catch here.
case io::EOF =>
fmt::fatal("Unexpected end of file");
// Any other io error will be caught here and we'll convert that
// to a string to print it.
case let err: io::error =>
fmt::fatal(io::strerror(err));
};
// Now we can print the buffer, but we only care about the
// number of bytes read in since we overallocated the buffer.
// We chop it down from index 0 to the number of bytes read in.
fmt::println(strings::fromutf8_unsafe(overview[..osz]))!;
// We can even seek to certain positions of a reader if needed.
// Since we read all of the contents of the file above we need
// to reset the read position back to the beginneing before we
// read from the file again or we'll get an EOF error.
//
// Seek position 0 exactly
io::seek(handle, 0, io::whence::SET)!;
// Reading the entire contents is fine for small files, but if
// we have a very large file it is better to buffer the read
// calls. For that we can use a buffered reader.
// Set up read and write buffers, but since we're only reading
// our write buffer is just an empty slice.
let rbuf: [os::BUFSZ]u8 = [0...];
let wbuf: []u8 = [];
const buf = bufio::init(handle, rbuf, wbuf);
// Start looping forever so we can read the file buffer
let wordcount = 0z;
for (true) {
// Let's read a whole word at a time. We can use this
// function and specify a SPACE character as the
// delimeter,
match (bufio::read_tok(&buf, ' ')) {
// If we get a slice of bytes back then we print the
// word and a newline.
case let tok: []u8 =>
wordcount += 1z;
fmt::println(strings::fromutf8_unsafe(tok))!;
// If we're done reading the whole file we print a
// message, but we also need to break from the infinite
// for loop.
case io::EOF =>
fmt::println("Done reading the whole file.")!;
break;
// Any other error
case let err: io::error =>
fmt::fatal(io::strerror(err));
};
};
fmt::printf("Total words: {}", wordcount)!;
};
$ hare run reading-files.ha
4/4 tasks completed (100%)
Let's look at ways to read files in Hare using the `os` and `io`
modules.
Let's
look
at
ways
to
read
files
in
Hare
using
the
`os`
and
`io`
modules.
Done reading the whole file.
Total words: 14
Back to table of contents