将文件扫描为字符串
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
请注意,我们正在检查输入和输出文件是否不同,以防止将文件映射到自身,这可能会导致无限循环并可能损坏文件。
我构建了一个函数,它将一个字符串作为输入并输出一个字符串。
我们称它为 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
请注意,我们正在检查输入和输出文件是否不同,以防止将文件映射到自身,这可能会导致无限循环并可能损坏文件。