文件操作

本指南介绍如何在 OCaml 中使用标准库执行基本文件操作。

相关模块的官方文档:包括初始打开的 Stdlib 和 Printf 模块的内核库。

缓冲通道

在 OCaml 中,打开文件的正常方式返回一个 **通道**。通道有两种类型:

  • 写入文件的通道:类型 out_channel
  • 从文件读取的通道:类型 in_channel

写入

要写入文件,您需要执行以下操作:

  1. 打开文件以获取 out_channel
  2. 写入通道
  3. 如果您想强制写入物理设备,则必须刷新通道,否则写入不会立即发生。
  4. 完成后,您可以关闭通道。这将自动刷新通道。

常用函数:open_outopen_out_binflushclose_outclose_out_noerr

标准 out_channelstdoutstderr

读取

要从文件读取数据,您需要执行以下操作:

  1. 打开文件以获取 in_channel
  2. 从通道读取字符。读取会消耗通道,因此如果您读取一个字符,通道将指向文件中的下一个字符。
  3. 当没有更多字符可读时,将引发 End_of_file 异常。通常,这就是您想要关闭通道的地方。

常用函数:open_inopen_in_binclose_inclose_in_noerr

标准 in_channelstdin

查找

每当您向通道写入或从通道读取内容时,当前位置都会更改为刚刚写入或读取内容的下一个字符之后。有时,您可能想要跳过文件中的特定位置,或从开头重新开始读取。对于指向普通文件的通道,可以使用 seek_inseek_out 来实现这一点。

注意事项

  • 如果您想要实际写入内容,请不要忘记刷新您的 out_channel。这在您写入非文件(例如标准输出 (stdout) 或套接字)时尤其重要。
  • 不要忘记关闭任何未使用的通道,因为操作系统对可以同时打开的文件数量有限制。您必须捕获文件操作期间发生的任何异常,关闭相应的通道,并重新引发异常。
  • Unix 模块提供对非缓冲文件描述符(以及其他内容)的访问。它提供与相应的标准通道具有相同名称的标准文件描述符:stdinstdoutstderr。因此,如果您执行 open Unix,您可能会遇到类型错误。如果您想确保您使用的是 stdout 通道而不是 stdout 文件描述符,可以在其来源模块名称之前加上它:Stdlib.stdout请注意,大多数似乎不属于任何模块的内容实际上都属于 Stdlib 模块,该模块会自动打开。
  • open_outopen_out_bin 会截断给定文件(如果它已经存在)!如果您想要其他行为,请使用 open_out_gen

示例

let file = "example.dat"
let message = "Hello!"

let () =
  (* Write message to file *)
  let oc = open_out file in
  (* create or truncate file, return channel *)
  Printf.fprintf oc "%s\n" message;
  (* write something *)
  close_out oc;

  (* flush and close the channel *)

  (* Read file and display the first line *)
  let ic = open_in file in
  try
    let line = input_line ic in
    (* read line, discard \n *)
    print_endline line;
    (* write the result to stdout *)
    flush stdout;
    (* write on the underlying device now *)
    close_in ic
    (* close the input channel *)
  with e ->
    (* some unexpected exception occurs *)
    close_in_noerr ic;
    (* emergency closing *)
    raise e

(* exit with error: files are closed but channels are not flushed *)

(* normal exit: all channels are flushed and closed *)

我们可以编译并运行此示例

$ ocamlopt -o file_manip file_manip.ml
$ ./file_manip
Hello!

仍然需要帮助?

帮助改进我们的文档

所有 OCaml 文档都是开源的。发现错误或不清楚的地方?提交一个拉取请求。

OCaml

创新。社区。安全。