OCaml's I/O system is completely imperative. You can use the high-level routines in the Pervasives module module, or the Posix-compliant routines in the Unix module (note that much of the Unix module will also work on Posix-compliant non-Unix systems like Windows). This page will cover only the Pervasives system, and will just cover the essential routines that are needed in most programs. See the documentation for more.
Opened files are called channels and come in two types: the type of input channels, in_channel, and the type of output channels: out_channel. This allows the type checker to detect any mixups between input files and output files at compile time!
Unix-style standard input, output and error channels are pre-opened and bound to the names stdin, stdout, and stderr respectively.
The printing functions all return unit. The two most important are print_string, which takes a single parameter of type string and prints it to stdout, and print_endline which is identical except that it also prints an end-of-line character(s) after printing the string. print_endline expr is equivalent to print_string expr; print_newline (). There are printing functions for types int, char and float as well, or you can use the various type conversion functions with the string printers.
# print_endline "foo";; foo - : unit = () # print_int 12; print_newline ();; 12 - : unit = () # print_endline (string_of_int 12);; 12 - : unit = () #
Analogous functions for printing to stderr exist, spelled similarly but with print replaced by prerr, e.g. prerr_endline, prerr_int, etc.
The various printing functions are awkward to use except in the simplest cases. You probably want to use the C-style formatted output functions in the Printf module. They work as you'd expect from experience with the analogous functions in other languages.
# Printf.printf "Formatted %s is %d times easier\n" "printing" 10;; Formatted printing is 10 times easier - : unit = () # Printf.sprintf "Formatted %s is %d times easier\n" "printing" 10;; - : string = "Formatted printing is 10 times easier\n" #
You can read from stdin with read_line, which takes a parameter of type unit and returns string (any end-of-line characters are removed on input).
Use open_in and open_out to open files for input and output respectively; each takes a filename as a string and returns a channel:
# let ic = open_in "/etc/motd" and oc = open_out "/tmp/feh";; val ic : in_channel = <abstr> val oc : out_channel = <abstr> #
open_in_gen and open_in_gen are like the previous functions, but take an extra argument which is a list of flags to control how the file is opened, and an extra argument to specify the permissions. Channels are closed with close_in and close_out.
There is a flotilla of output functions that apply to an out_channel. The most useful are output_char, output_string and output (which takes a string as a buffer along with an offset and length):
# output_string oc "foo";; - : unit = () # let buf = "a very very very very long string";; val buf : string = "a very very very very long string" # output oc buf 2 4;; - : unit = () # close_out oc;; - : unit = () #
The expression output oc buf 2 4 writes (the first) "very" to the output file. Printf.fprintf does formatted output like Printf.printf except it writes on the out_channel given as an argument.
The most useful of the many general input functions are input_char, input_line and input, which are analogous to the similarly-named output functions.