Here’s something that I’ve used before:
open! Core
module H = Hashtbl.Make_binable(Int)
let write_binary file value_size value_writer table =
let size = H.bin_size_t value_size table in
let bs = Core.Bigstring.create size in
H.bin_write_t value_writer ~pos:0 bs table |> ignore;
let fd = Unix.openfile ~mode:[O_WRONLY; O_CREAT; O_TRUNC] file in
Core.Bigstring.write fd bs |> ignore;
Unix.close fd
let read_binary file read_value =
let file_size fd =
let pos = Unix.lseek fd Int64.zero ~mode:SEEK_CUR in
let bytes = Unix.lseek fd Int64.zero ~mode:SEEK_END in
let _ = Unix.lseek fd pos ~mode:SEEK_SET in
bytes
in
let fd = Unix.openfile ~mode:[O_RDONLY] file in
let size = file_size fd in
let bs = Core.Bigstring.create Int64.(to_int_exn size) in
Core.Bigstring.read fd bs |> ignore;
Unix.close fd;
let pos_ref = ref 0 in
H.bin_read_t read_value bs ~pos_ref
;;
let run() =
let table = H.create() in
H.set table ~key:10 ~data:"Hello";
H.set table ~key:20 ~data:"Awesome";
write_binary "table.bin" String.bin_size_t String.bin_write_t table;
let table = read_binary "table.bin" String.bin_read_t in
H.iteri table ~f:(fun ~key ~data ->
Printf.printf "Key %d - Value %s\n" key data
)
When run:
$ _build/default/bin/main.exe
Key 10 - Value Hello
Key 20 - Value Awesome