如何在OCaml中下载、解压缩和处理gzip文件?
我希望我的ocaml应用程序直接下载、解压缩(gzip),然后逐行处理生成的文本文件,而不使用临时文件和外部程序 我看的库是cohttp、ocurl和camlzip。不幸的是,我没有找到让他们一起工作的好方法 OCaml实现这一点的方法是什么?您可以使用管道和线程使ocurl和camlzip协同工作。概念证明:如何在OCaml中下载、解压缩和处理gzip文件?,ocaml,Ocaml,我希望我的ocaml应用程序直接下载、解压缩(gzip),然后逐行处理生成的文本文件,而不使用临时文件和外部程序 我看的库是cohttp、ocurl和camlzip。不幸的是,我没有找到让他们一起工作的好方法 OCaml实现这一点的方法是什么?您可以使用管道和线程使ocurl和camlzip协同工作。概念证明: #use "topfind";; #thread;; #require "unix";; #require "curl";; #require "zip";; let () = Cur
#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源代码文件
下载\u gunzip\u lines.ml
:
open Printf
let read_all_lines ic =
Seq.unfold (fun () -> try Some(input_line ic, ()) with _ -> None) ()
let () =
match Sys.argv with
| [|_; url|] ->
read_all_lines(Unix.open_process_in(sprintf "wget -q -O - %s | gunzip" url))
|> Seq.iter (fun line -> printf "%d\n" (String.length line))
| _ -> eprintf "Usage: download_gunzip_lines <url>"
然后:
要构建它,请执行以下操作:
./_build/default/download_gunzip_lines.exe http://www.o-bible.com/download/kjv.gz
在詹姆斯国王的圣经副本上运行它
更好的是,使用Bash脚本中的OCaml代码运行
wget
和gunzip
,然后在OCaml中处理这些行。我在OPAM repo中找不到这样的库。现在可能没有。临时文件有什么问题吗?我只是希望有一些简单明了的方法,就像在许多其他语言中一样,例如:new GzipInputStream(url.openStream()).foreach(println)@gruenewa不幸的是,这样的东西经常丢失,这是编写这样的东西的好机会
dune build --profile release
./_build/default/download_gunzip_lines.exe http://www.o-bible.com/download/kjv.gz