ocaml - 如何在 OCaml 中下载、解压缩和处理 gzip 文件?

标签 ocaml

我希望我的 ocaml 应用程序直接下载、解压缩 (gzip),然后逐行处理生成的文本文件,而不使用临时文件和外部程序。

我查看的库是 cohttpocurlcamlzip。不幸的是,我没有找到让它们一起工作的好方法。

OCaml 将如何实现这一点?

最佳答案

您可以使用管道和线程使 ocurlcamlzip 协同工作。概念证明:

#use "topfind";;
#thread;;
#require "unix";;
#require "curl";;
#require "zip";;

let () = Curl.(global_init CURLINIT_GLOBALALL)

let download url oc =
  let open Curl in
  let h = init () in
  setopt h (CURLOPT_URL url);
  setopt h (CURLOPT_WRITEFUNCTION (fun x -> output_string oc x; String.length x));
  perform h;
  cleanup h

let read_line really_input =
  let buf = Buffer.create 256 in
  try
    while true do
      let x = " " in
      let () = really_input x 0 1 in
      if x = "\n" then raise Exit else Buffer.add_string buf x;
    done;
    assert false
  with
  | Exit -> Buffer.contents buf
  | End_of_file -> if Buffer.length buf = 0 then raise End_of_file else Buffer.contents buf

let curl_gzip_iter f url =
  let ic, oc = Unix.pipe () in
  let ic = Unix.in_channel_of_descr ic and oc = Unix.out_channel_of_descr oc in
  let t = Thread.create (fun () -> download url oc; close_out oc) () in
  let zic = Gzip.open_in_chan ic in
  let zii = Gzip.really_input zic in
  let () =
    try
      while true do
        let () = f (read_line zii) in ()
      done;
      assert false
    with
    | End_of_file -> ()
  in
  Gzip.close_in zic;
  Thread.join t

let () = curl_gzip_iter print_endline "file:///tmp/toto.gz"

但是,当必须处理错误时,这会变得很痛苦。

关于ocaml - 如何在 OCaml 中下载、解压缩和处理 gzip 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38704239/

相关文章:

shell - OCaml中的多行shebang?

performance - 多态变体中的内联记录?

Ocaml的命名参数

ocaml - OCaml方差(+'a,-'a)和不变性

command-line - 动态实例化 OCaml 中的模块

ocaml - 在 OCaml 中管理 GPU 内存

module - OCaml 模块如何导出依赖模块中定义的字段?

syntax - "open!"是什么意思?

functional-programming - 在 OCaml 中实现快速排序 : don't understand what's going wrong?

ocaml - ocaml 中的类型问题