transparently open compressed files in ocaml
The Pervasive.in_channel
in the ocaml std library is not
extensible. If you want to mix different in_channel
, for
example, one from Pervasive and on from the Gzip library, then you are
in trouble. The good fellows of extlib solved this problem providing
an extensible stream data type in the IO library [1] . This is a small
example using that module.
let gzip_open_in file =
let ch = Gzip.open_in file in
IO.create_in
~read:(fun () -> Gzip.input_char ch)
~input:(Gzip.input ch)
~close:(fun () -> Gzip.close_in ch)
let std_open_in file =
let ch = open_in file in
IO.create_in
~read:(fun () -> input_char ch)
~input:(input ch)
~close:(fun () -> close_in ch)
let main () =
let file = Sys.argv.(1) in
let ch =
if Filename.check_suffix file ".gz" then gzip_open_in file
else std_open_in file
in
try
while true do
print_endline (IO.read_line ch)
done
with End_of_file ->
IO.close_in ch
;;
main ();;
untested compile commands (I use ocamlbuild + custom myocamlbuild.ml):
ocamlfind ocamldep -package extlib -package zip -modules test.ml > test.ml.depends
ocamlfind ocamlc -c -package extlib -package zip -o test.cmo test.ml
ocamlfind ocamlc -linkpkg -package extlib -package zip test.cmo -o test.byte
[1] http://ocaml-lib.sourceforge.net/doc/IO.html