我有許多行的文本文件。我想寫一個簡單的OCaml程序,它可以逐行處理這個文件,也許可以打印這行。OCaml - 致命錯誤:使用`| |時發生異常Sys_error(「Broken pipe」)|頭上`包含很多行輸出
爲了編寫這個程序,我首先創建了一個較小的文件,使用更少的行 - 這樣程序就能夠更快地完成執行。
$ wc -l input/master
214745 input/master
$ head -50 input/master > input/small-master
下面是簡單的樣板filter.ml
程序我寫道:
open Core.Std;;
open Printf;;
open Core.In_channel;;
if Array.length Sys.argv >= 2 then begin
let rec process_lines ?ix master_file =
let ix = match ix with
| None -> 0
| Some x -> x
in
match input_line master_file with
| Some line -> (
if ix > 9 then printf "%d == %s\n" ix line;
process_lines ~ix:(ix+1) master_file
)
| None -> close master_file
in
let master_file = create Sys.argv.(1) in
process_lines master_file
end
這需要輸入文件的位置作爲命令行參數,對於閱讀本文件創建一個文件句柄,並調用遞歸函數process_lines
將此文件句柄作爲參數。
process_lines
使用可選參數ix
來計算行號,因爲它從行中讀取文件句柄。 process_lines只是將從file_handle
讀取的行打印到標準輸出。
然後,當我在較小的輸入文件和管道執行程序輸出到Linux head
命令一切正常:
$ ./filter.native input/small-master |head -2
10 == 1000032|BINCH JAMES G|4|2012-11-13|edgar/data/1000032/0001181431-12-058269.txt
11 == 1000032|BINCH JAMES G|4|2012-12-03|edgar/data/1000032/0001181431-12-061825.txt
而且,當我在較大的文件我執行程序看到一個破碎的管道錯誤:
$ ./filter.native input/master |head -2
10 == 1000032|BINCH JAMES G|4|2012-11-13|edgar/data/1000032/0001181431-12-058269.txt
11 == 1000032|BINCH JAMES G|4|2012-12-03|edgar/data/1000032/0001181431-12-061825.txt
Fatal error: exception Sys_error("Broken pipe")
Raised by primitive operation at file "pervasives.ml", line 264, characters 2-40
Called from file "printf.ml", line 615, characters 15-25
Called from file "find.ml", line 13, characters 21-48
Called from file "find.ml", line 19, characters 2-27
我知道,當一個管(在這種情況下head
命令)的讀者在這種情況下退出該管的作家之前(我的OCaml程序會發生這樣的水管壞了的錯誤)已經完成了寫作G。這就是爲什麼如果我使用tail
命令作爲讀者,我永遠不會得到這樣的錯誤。
但是,當文件的行數較少時,爲什麼沒有發生斷管錯誤?