将文件扫描为字符串

Scanning a file as a string

我构建了一个函数,它将一个字符串作为输入并输出一个字符串。 我们称它为 f。 我想将字符串扫描到文件 input.txt 并将我的函数应用于此字符串并将其写入另一个文件 output.txt.

其他问题:如果文件太大,可能无法扫描。因此我有一个函数 f_line,我想逐行扫描 input.txt 的每一行并将此函数应用于这一行,并将每个输出写入文件中的文件 output.txt. 我该怎么做?

我终于找到了一个简单的解决方案,代码如下:

let transform_files_by_line 
(f_line : string -> string) (in_filename : string) 
(out_filename : string) =
let input_chan = open_in in_filename 
and output_chan = open_out out_filename
in
let rec transform_rec () =
    let str = input_line input_chan in
      output_string output_chan (f_line str) ;
      transform_rec () ;
in
 try (transform_rec ()) with
End_of_file -> (
  close_in input_chan;
  close_out output_chan;) ;;

你基本上想要 map 一个包含你的函数的文件到另一个文件,就像你映射列表一样,例如,

# List.map String.uppercase_ascii ["hello"; "world"];;
- : string list = ["HELLO"; "WORLD"]

在 OCaml 中,文件是通过称为通道的抽象来读取和写入的。通道是有方向的,即输入通道和输出通道是有区别的。要打开输入通道,请使用 open_in 函数,要关闭它,请使用 close_in。输出通道的相应函数具有 _out 前缀。

要逐行映射两个通道,我们需要从一个通道读取一行,将我们的转换 f 应用于每一行并写入输出通道,直到第一个通道引发 End_of_file 表示没有更多数据的异常,例如,

let rec map_channels input output f =
  match f (input_line input) with
  | exception End_of_file -> flush output
  | r ->
    output_string output r;
    output_char output '\n';
    map_channels input output f

现在我们可以使用这个函数来编写一个函数,它接受文件名而不是频道,例如

let map_files input output f =
  if input = output
  then invalid_arg "the input and output files must differ";
  let input = open_in input in
  let output = open_out output in
  map_channels input output f;
  close_in input;
  close_out output

请注意,我们正在检查输入和输出文件是否不同,以防止将文件映射到自身,这可能会导致无限循环并可能损坏文件。