檔案操作

這是使用標準函式庫在 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) 或 socket,這一點尤其重要。
  • 不要忘記關閉任何未使用的通道,因為作業系統同時開啟的檔案數量有限制。您必須捕獲檔案操作期間發生的任何例外,關閉對應的通道,然後重新引發例外。
  • 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 文件都是開放原始碼。看到錯誤或不清楚的地方嗎?提交 pull request。

OCaml

創新、社群、安全。