檔案操作
這是使用標準函式庫在 OCaml 中進行基本檔案操作的指南。
相關模組的官方文件:包含最初開啟的 Stdlib 和 Printf 模組的核心函式庫。
緩衝通道
在 OCaml 中開啟檔案的正常方式會傳回一個通道。通道有兩種:
- 寫入檔案的通道:類型為
out_channel
- 從檔案讀取的通道:類型為
in_channel
寫入
若要寫入檔案,您可以執行以下操作:
- 開啟檔案以取得
out_channel
- 寫入通道
- 如果您想要強制寫入到實體裝置,您必須刷新通道,否則寫入不會立即發生。
- 完成後,您可以關閉通道。這會自動刷新通道。
常用函數:open_out
、open_out_bin
、flush
、close_out
、close_out_noerr
標準 out_channel
:stdout
、stderr
讀取
若要從檔案讀取資料,您可以執行以下操作:
- 開啟檔案以取得
in_channel
- 從通道讀取字元。讀取會消耗通道,因此如果您讀取一個字元,通道會指向檔案中的下一個字元。
- 當沒有更多字元可讀取時,會引發
End_of_file
例外。通常,這也是您想要關閉通道的地方。
常用函數:open_in
、open_in_bin
、close_in
、close_in_noerr
標準 in_channel
:stdin
搜尋
每當您寫入或讀取通道的內容時,目前位置會變更為剛寫入或讀取內容之後的下一個字元。有時,您可能想要跳到檔案中的特定位置,或從頭開始重新讀取。對於指向正規檔案的通道,可以使用 seek_in
或 seek_out
來實現。
注意事項
- 如果您想要實際寫入內容,請不要忘記刷新您的
out_channel
。如果您寫入的不是檔案,例如標準輸出 (stdout
) 或 socket,這一點尤其重要。 - 不要忘記關閉任何未使用的通道,因為作業系統同時開啟的檔案數量有限制。您必須捕獲檔案操作期間發生的任何例外,關閉對應的通道,然後重新引發例外。
Unix
模組提供對非緩衝檔案描述符的存取權,以及其他功能。它提供的標準檔案描述符與對應的標準通道具有相同的名稱:stdin
、stdout
和stderr
。因此,如果您執行open Unix
,可能會出現類型錯誤。如果您想要確保使用stdout
通道而不是stdout
檔案描述符,您可以在其前面加上它來源的模組名稱:Stdlib.stdout
。請注意,大多數似乎不屬於任何模組的東西實際上屬於Stdlib
模組,該模組會自動開啟。open_out
和open_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!