如何控制Scanf.Scanning的缓冲区?

时间:2017-02-18 00:12:59

标签: ocaml

Scanf模块似乎表现得有点像 违反直觉,因为它不尊重国家 基础渠道:

(* prepare test data *)
let () =
  let oc = open_out "test.txt" in
  output_string oc "abcdefghij\n";
  close_out oc
;;

let ic = open_in "test.txt"

(* ic at offset 0: “ab…” *)
let () =
  let sc = Scanf.Scanning.from_channel ic in
  let s = Scanf.bscanf sc "%2s" (fun s -> s) in
  Printf.eprintf "read [%s]\n" s (* -> [ab] *)
;; (* sc out of scope at this point *)

(* hint: close ic here and reopen for expected result *)
seek_in ic 4

(* ic at offset 4: “ef…” *)
let () =
  let sc = Scanf.Scanning.from_channel ic in
  let s = Scanf.bscanf sc "%2s" (fun s -> s) in
  Printf.eprintf "read [%s]\n" s (* -> [cd] ‽ *)
;;

close_in ic

显然Scanning.t的内部缓冲区存在 除非重新创建频道。有没有另一种方法来强迫 重新同步? docs https://www.consul.io/docs/agent/http/health.html 声称“阅读从目前的ic读取位置开始。”

我很欣赏指向这种行为的指针 记录。

1 个答案:

答案 0 :(得分:1)

仅仅根据一般设计原则,我会说调用Scanf.Scanning.from_channel会将频道的责任转移到Scanf模块。如果你走到Scanf模块的后面并直接操纵频道(就像你在seek_in那样做),事情就无法保证工作。

与我使用的几乎每个分层I / O库的工作方式类似。例如,您不能使用Unix stdio中的fdopen()并期望通过FILE抽象读取数据,同时还以任意方式操作底层文件描述符。

如果文档提到这些问题(在这两种情况下)可能会很好。