如何使用Bigarray.map_file写入新文件

时间:2018-07-16 13:14:27

标签: ocaml

我要使用Bigarray.map_file创建一个新文件,如下所示:

let file_write_ba path =
    try
        let fd = Unix.openfile path ~mode:[Unix.O_WRONLY;Unix.O_CREAT] in
        let ba = Bigarray.array1_of_genarray (Unix.map_file fd 
            ~pos:0L Bigarray.char Bigarray.c_layout true [|(-1)|])
        in
        Some ba
    with
    | _ -> Printf.printf "some error"; None

let write_chunk ~inba ~outba ~inpos ~outpos ~size =
    let sub_in = Bigarray.Array1.sub inba inpos size in
    let sub_out = Bigarray.Array1.sub outba outpos size in
    Bigarray.Array1.blit sub_in sub_out

let do_write databa =
    let outba = file_write_ba "some_temp_file" in
    write_chunk databa outba 0 0 (Bigarray.Array1.dim databa)

因此它无法创建sub_out,但是后来我不知道如何解决在map_file上扩展bigarray的问题。

1 个答案:

答案 0 :(得分:1)

要提及的三件事:

  1. mmap()不会更改文件大小。您创建了一个大小为0的文件,因此它始终保持大小为0,并且没有任何内容写入该文件。您必须在mmap()调用之前通过向其写入数据或调用fallocate(不确定ocaml是否具有映射关系)来调整文件的大小。

  2. 使用mmap()写入文件效率很低。清除bigarary时,写入每个页面的第一个字节会导致页面错误。然后,内核从文件系统读取相应的数据块,然后重试写入。然后写操作将更改页面中的字节。稍后,内核会将该页面写回到文件中。

  3. 错误处理几乎是不可能的。对mmaped文件的写入错误将在以后的某个随机时间发生,并且无法捕获它们。