In Ocaml, I/O operations are performed on “channels” that we can think of as files.
There are two types of channels:
type in_channel can be used to read input into a programtype out_channel that can be used for output.There are also three “pre-opened channels”:
val stdin : in_channel (the standard input)val stdout : out_channel (the standard output)val stderr : out_channel (for logging/printing errors)The common way to open a channel is by file name:
val open_out : string -> out_channel takes a filename as input and returns an out_channelval open_in : string -> in_channel takes a filename as input and returns an in_channelThese can raise Sys_error if the file cannot be opened.
Once a program has finished using a channel, it should be closed with:
val close_out : out_channel -> unit orval close_in : in_channel -> unitTo read from a file, the most common methods are
val input_char : in_channel -> char - reads a single charval input_line : in_channel -> string - reads a line, trims newline.val read_line : unit -> string (input_line from stdin)If the channel (file) does not have more data, these raise End_of_file.
A common pattern is the “stream” approach:
unit -> string optionSome vEnd_of_file is raised, close the channel and return Nonelet stream_of_file f =
let ic = open_in f in
let nextline () =
begin
try Some (input_line ic) with
End_of_file -> let () = close_in ic in None
end
in nextlineAnother approach makes a list of all lines in the file:
Still not quite right:
let get_file_lines f =
let ic = open_in f in
let rec gfl_helper acc =
try gfl_helper ((input_line ic)::acc)
with End_of_file -> (let () = close_in ic in acc)
in List.rev (gfl_helper [])try should wrap only the input_line call:
To write to an out_channel, the commonly used functions are:
val output_char : out_channel -> char -> unitval output_string : out_channel -> string -> unitThese can raise Sys_error if writing fails.
Example: write a string list to a file, one line at a time:
What about writing a list of int*int pairs, separated by tabs, followed by newlines?
The Printf module provides a mechanism for formatted output:
Printf.sprintf writes formatted input to a stringPrintf.printf prints formatted input to stdoutPrintf.fprintf oc prints formatted input to oc : out_channelPrintf.printf <fs> is a function with the correct number of inputs to match the format string <fs>:
More on conversions in Hickey and the Ocaml manual
Example: write_pair_list again…
cs2041.org