mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 11:15:32 -05:00
Sequence.IO module, a very very simple way to read/write files
This commit is contained in:
parent
185cf14f28
commit
3458581ff2
2 changed files with 104 additions and 0 deletions
53
sequence.ml
53
sequence.ml
|
|
@ -716,3 +716,56 @@ let to_string ?sep pp_elt seq =
|
||||||
let buf = Buffer.create 25 in
|
let buf = Buffer.create 25 in
|
||||||
pp_buf ?sep (fun buf x -> Buffer.add_string buf (pp_elt x)) buf seq;
|
pp_buf ?sep (fun buf x -> Buffer.add_string buf (pp_elt x)) buf seq;
|
||||||
Buffer.contents buf
|
Buffer.contents buf
|
||||||
|
|
||||||
|
(** {2 Basic IO} *)
|
||||||
|
|
||||||
|
module IO = struct
|
||||||
|
let lines_of ?(mode=0o644) ?(flags=[Open_rdonly]) filename =
|
||||||
|
fun k ->
|
||||||
|
let ic = open_in_gen flags mode filename in
|
||||||
|
try
|
||||||
|
while true do
|
||||||
|
let line = input_line ic in
|
||||||
|
k line
|
||||||
|
done
|
||||||
|
with
|
||||||
|
| End_of_file -> close_in ic
|
||||||
|
| e -> close_in_noerr ic; raise e
|
||||||
|
|
||||||
|
let chunks_of ?(mode=0o644) ?(flags=[]) ?(size=1024) filename =
|
||||||
|
fun k ->
|
||||||
|
let ic = open_in_gen flags mode filename in
|
||||||
|
try
|
||||||
|
let buf = String.create size in
|
||||||
|
let n = ref 0 in
|
||||||
|
let stop = ref false in
|
||||||
|
while not !stop do
|
||||||
|
n := 0;
|
||||||
|
(* try to read [size] chars. If [input] returns [0] it means
|
||||||
|
the end of file, so we stop, but first we yield the current chunk *)
|
||||||
|
while !n < size && not !stop do
|
||||||
|
let n' = input ic buf !n (size - !n) in
|
||||||
|
if n' = 0 then stop := true else n := !n + n';
|
||||||
|
done;
|
||||||
|
if !n > 0
|
||||||
|
then k (String.sub buf 0 !n)
|
||||||
|
done;
|
||||||
|
close_in ic
|
||||||
|
with e ->
|
||||||
|
close_in_noerr ic;
|
||||||
|
raise e
|
||||||
|
|
||||||
|
let write_to ?(mode=0o644) ?(flags=[Open_creat;Open_wronly]) filename seq =
|
||||||
|
let oc = open_out_gen flags mode filename in
|
||||||
|
try
|
||||||
|
seq (fun s -> output oc s 0 (String.length s));
|
||||||
|
close_out oc
|
||||||
|
with e ->
|
||||||
|
close_out oc;
|
||||||
|
raise e
|
||||||
|
|
||||||
|
let write_lines ?mode ?flags filename seq =
|
||||||
|
write_to ?mode ?flags filename (snoc (intersperse "\n" seq) "\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
51
sequence.mli
51
sequence.mli
|
|
@ -534,3 +534,54 @@ val pp_buf : ?sep:string -> (Buffer.t -> 'a -> unit) ->
|
||||||
|
|
||||||
val to_string : ?sep:string -> ('a -> string) -> 'a t -> string
|
val to_string : ?sep:string -> ('a -> string) -> 'a t -> string
|
||||||
(** Print into a string *)
|
(** Print into a string *)
|
||||||
|
|
||||||
|
(** {2 Basic IO}
|
||||||
|
|
||||||
|
Very basic interface to manipulate files as sequence of chunks/lines. The
|
||||||
|
sequences take care of opening and closing files properly; every time
|
||||||
|
one iterates over a sequence, the file is opened/closed again.
|
||||||
|
|
||||||
|
Example: copy a file ["a"] into file ["b"], removing blank lines:
|
||||||
|
|
||||||
|
{[
|
||||||
|
Sequence.(IO.lines_of "a" |> filter (fun l-> l<> "") |> IO.write_lines "b");;
|
||||||
|
]}
|
||||||
|
|
||||||
|
By chunks of [4096] bytes:
|
||||||
|
|
||||||
|
{[
|
||||||
|
Sequence.IO.(chunks_of ~size:4096 "a" |> write_to "b");;
|
||||||
|
]}
|
||||||
|
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
module IO : sig
|
||||||
|
val lines_of : ?mode:int -> ?flags:open_flag list ->
|
||||||
|
string -> string t
|
||||||
|
(** [lines_of filename] reads all lines of the given file. It raises the
|
||||||
|
same exception as would opening the file and read from it, except
|
||||||
|
from [End_of_file] (which is caught). The file is {b always} properly
|
||||||
|
closed.
|
||||||
|
Every time the sequence is iterated on, the file is opened again, so
|
||||||
|
different iterations might return different results
|
||||||
|
@param mode default [0o644]
|
||||||
|
@param flags default: [[Open_rdonly]] *)
|
||||||
|
|
||||||
|
val chunks_of : ?mode:int -> ?flags:open_flag list -> ?size:int ->
|
||||||
|
string -> string t
|
||||||
|
(** Read chunks of the given [size] from the file. The last chunk might be
|
||||||
|
smaller. Behaves like {!lines_of} regarding errors and options.
|
||||||
|
Every time the sequence is iterated on, the file is opened again, so
|
||||||
|
different iterations might return different results *)
|
||||||
|
|
||||||
|
val write_to : ?mode:int -> ?flags:open_flag list ->
|
||||||
|
string -> string t -> unit
|
||||||
|
(** [write_to filename seq] writes all strings from [seq] into the given
|
||||||
|
file. It takes care of opening and closing the file.
|
||||||
|
@param mode default [0o644]
|
||||||
|
@param flags used by [open_out_gen]. Default: [[Open_creat;Open_wronly]]. *)
|
||||||
|
|
||||||
|
val write_lines : ?mode:int -> ?flags:open_flag list ->
|
||||||
|
string -> string t -> unit
|
||||||
|
(** Same as {!write_to}, but intercales ['\n'] between each string *)
|
||||||
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue