Reading Files in OCaml Our first example demonstrates reading files in OCaml. Reading and writing files are basic tasks needed for many OCaml programs. Let’s look at some examples of reading files.
open Core
(* Reading files requires checking most calls for errors.
This helper will streamline our error checks below. *)
let check_exn result =
match result with
| Ok x -> x
| Error e -> raise ( Unix . Unix_error ( e , "" , "" ))
let () =
(* Perhaps the most basic file reading task is
slurping a file's entire contents into memory. *)
let dat = In_channel . read_all "/tmp/dat" in
printf "%s" dat ;
(* You'll often want more control over how and what
parts of a file are read. For these tasks, start
by opening a file to obtain an In_channel value. *)
let ic = In_channel . create "/tmp/dat" in
(* Read some bytes from the beginning of the file.
Allow up to 5 to be read but also note how many
actually were read. *)
let b1 = Bytes . create 5 in
let n1 = check_exn ( In_channel . input ic ~ buf : b1 ~ pos : 0 ~ len : 5 ) in
printf "%d bytes: %s \n " n1 ( Bytes . sub_string b1 0 n1 );
(* You can also seek to a known location in the file
and read from there. *)
check_exn ( In_channel . seek ic 6L );
let b2 = Bytes . create 2 in
let n2 = check_exn ( In_channel . input ic ~ buf : b2 ~ pos : 0 ~ len : 2 ) in
printf "%d bytes @ %d: %s \n " n2 6 ( Bytes . to_string b2 );
(* Other methods of seeking are relative to the
current cursor position, *)
check_exn ( In_channel . seek ic ( Int64 . of_int 4 ));
(* and relative to the end of the file. *)
check_exn ( In_channel . seek ic ( Int64 . of_int (- 10 )));
(* The Core library provides some functions that may
be helpful for file reading. For example, reads
like the ones above can be more robustly
implemented with In_channel.really_input. *)
check_exn ( In_channel . seek ic 6L );
let b3 = Bytes . create 2 in
check_exn ( In_channel . really_input ic b3 0 2 );
printf "%d bytes @ %d: %s \n " 2 6 ( Bytes . to_string b3 );
(* There is no built-in rewind, but
seek to 0 accomplishes this. *)
check_exn ( In_channel . seek ic 0L );
(* The Core library also implements a buffered
reader that may be useful both for its efficiency
with many small reads and because of the additional
reading methods it provides. *)
let reader = Stdio . In_channel . create "/tmp/dat" in
let line = Stdio . In_channel . input_line_exn reader in
printf "First line: %s \n " line ;
(* Close the file when you're done (usually this would
be scheduled immediately after opening with
`finally`). *)
In_channel . close ic ;
Stdio . In_channel . close reader
To run this program:
$ echo "hello" > /tmp/dat
$ echo "ocaml" >> /tmp/dat
$ ocaml reading_files.ml
hello
ocaml
5 bytes: hello
2 bytes @ 6: oc
2 bytes @ 6: oc
First line: hello
This example demonstrates various ways to read files in OCaml, including reading entire files, seeking to specific positions, and using buffered readers. It also shows how to handle potential exceptions when working with files.
Next, we’ll look at writing files.