Zipc is an in-memory ZIP archive and deflate compression codec. Other compression formats in ZIP archives can be supported by using third-party libraries.
See the quick start and the limitations.
zipc
Zipc
ZIP archives.Zipc_deflate
Deflate and zlib compressed data formats.These convenience functions to read and write files or standard streams are used below.
Reads stdin
or a file's bytes to a string.
let read_file file =
let read file ic = try Ok (In_channel.input_all ic) with
| Sys_error e -> Error (Printf.sprintf "%s: %s" file e)
in
let binary_stdin () = In_channel.set_binary_mode In_channel.stdin true in
try match file with
| "-" -> binary_stdin (); read file In_channel.stdin
| file -> In_channel.with_open_bin file (read file)
with Sys_error e -> Error e
Writes a string's bytes to stdout
or a file.
let write_file file s =
let write file s oc = try Ok (Out_channel.output_string oc s) with
| Sys_error e -> Error (Printf.sprintf "%s: %s" file e)
in
let binary_stdout () = Out_channel.(set_binary_mode stdout true) in
try match file with
| "-" -> binary_stdout (); write file s Out_channel.stdout
| file -> Out_channel.with_open_bin file (write file s)
with Sys_error e -> Error e
This extracts the data of a file named path
in a ZIP archive read from the file archive
:
let unzip_path ~path ~archive =
let ( let* ) = Result.bind in
let file_error file msg = Printf.sprintf "%s: %s" file msg in
let* s = read_file archive in
Result.map_error (file_error archive) @@
let* z = Zipc.of_binary_string s in
Result.map_error (file_error path) @@
match Option.map Zipc.Member.kind (Zipc.find path z) with
| None -> Error "No such path"
| Some Zipc.Member.Dir -> Error "Is a directory"
| Some Zipc.Member.File file ->
let* data = Zipc.File.to_binary_string file in
Ok (Zipc.Fpath.sanitize path, data)
This function reads the file file
, adds it under its basename to an empty ZIP archive and writes the result to the file archive
.
let zip_file ?(compress = true) ~file ~archive () =
let ( let* ) = Result.bind in
let file_error file msg = Printf.sprintf "%s: %s" file msg in
let* s = read_file file in
let* m =
Result.map_error (file_error file) @@
let path = Filename.basename file in
let* file = match compress with
| true -> Zipc.File.deflate_of_binary_string s
| false -> Zipc.File.stored_of_binary_string s
in
Zipc.Member.make ~path (Zipc.Member.File file)
in
let* s = Zipc.to_binary_string (Zipc.add m Zipc.empty) in
write_file archive s
Note that in this example the actual permissions and modification time of file
are not preserved in the archive, we rely on defaults. A bit more work with the Unix
module would be needed. See for example the source of the zipc
tool in the distribution.
If you would like to see js_of_ocaml
examples look at the test
directory in the development repository of the library.