This is a guide to basic file manipulation in OCaml using only what the standard library provides.
Official documentation for the modules of interest: Pervasives, Printf.
The standard library doesn't provide functions that directly read a file into a string or save a string into a file. Such functions can be found in third-party libraries such as Extlib. See Std.input_file and Std.output_file.
The normal way of opening a file in OCaml returns a channel. There are two kinds of channels:
For writing into a file, you would do this:
Commonly used functions:
For reading data from a file you would do this:
End_of_fileexception is raised. Often, this is where you want to close the channel.
Commonly used functions:
Whenever you write or read something to or from a channel, the current position changes to the next character after what you just wrote or read. Occasionally, you may want to skip to a particular position in the file, or restart reading from the beginning. This is possible for channels that point to regular files, use
out_channels if you want to actually write something. This is particularly important if you are writing to non-files such as the standard output (
stdout) or a socket.
Unixmodule provides access to non-buffered file descriptors among other things. It provides standard file descriptors that have the same name as the corresponding standard channels:
stderr. Therefore if you do
open Unix, you may get type errors. If you want to be sure that you are using the
stdoutchannel and not the
stdoutfile descriptor, you can prepend it with the module name where it comes from:
Pervasives.stdout. Note that most things that don't seem to belong to any module actually belong to the
Pervasivesmodule, which is automatically opened.
open_out_bintruncate the given file if it already exists! Use
open_out_genif you want an alternate behavior.
open Printf let file = "example.dat" let message = "Hello!" let _ = (* Write message to file *) let oc = open_out file in (* create or truncate file, return channel *) fprintf oc "%s\n" message; (* write something *) close_out oc; (* flush and close the channel *) (* Read file and display the first line *) let ic = open_in file in try let line = input_line ic in (* read line from in_channel and discard \n *) print_endline line; (* write the result to stdout *) flush stdout; (* write on the underlying device now *) close_in ic (* close the input channel *) with e -> (* some unexpected exception occurs *) close_in_noerr ic; (* emergency closing *) raise e (* exit with error: files are closed but channels are not flushed *) (* normal exit: all channels are flushed and closed *)