[英]How can I check if a text file is empty in Haskell?
如何檢查Haskell中的文本文件是否為空?
我已經嘗試過:
main = do
contents <- getContents
if null contents then do
putStrLn "File was empty"
return()
else do
putStrLn "File was not empty"
return
實際上,問題主要出在您的格式化中,而不是您的邏輯中!
在Haskell中,空格很重要,請參閱此Wiki頁面 。 遵循其規則,並在最后一個return
語句中修復次要錯字(您需要像之前一樣返回unit ()
):
main = do
contents <- getContents
if null contents then do
putStrLn "File was empty"
return ()
else do
putStrLn "File was not empty"
return ()
這應該完美地工作。 但是,這並不是真正的最佳實踐-在if
表達式的每個部分中都有do
塊,您可以構造一個新的monadic動作,這是不必要的。 鑒於putStrLn
無論如何putStrLn
返回IO ()
,您可以執行以下操作:
main = do
contents <- getContents
if null contents then
putStrLn "File was empty"
else
putStrLn "File was not empty"
請記住, if ... then x else y
表達式返回與x
和y
類型相同的值-在這里, x
和y
都具有IO ()
類型,因此該表達式返回IO ()
,即為什么可以在此do
塊中使用它。
請注意,這不會檢查文件是否為空,而是會檢查標准輸入是否為空:如果將文件中的輸入管道傳輸到程序的stdin中就可以了,但是如果您想實際讀取文件,則應該查看readFile
您幾乎不需要更改此程序! 像下面這樣的東西可以解決問題:
main = do
putStrLn "Enter the file path:"
path <- getLine
contents <- readFile path
if null contents ...
@hnefatl的答案很好,這可能就是您要使原始代碼正常工作所需要的。 但是,如果其他人在試圖弄清楚如何檢查文件是否為空時偶然發現了這個問題,則會給出更高級(但更可取)的答案。
在“真實” Haskell代碼,假設你嘗試檢查一個純文本文件的大小,你可能會使用getFileStatus
和輔助功能, fileSize
從System.Posix
,在這個問題討論: 什么是檢索的最佳方式haskell中文件的大小?
具體來說,類似以下功能的功能將在Linux上運行:
import System.Posix
isEmpty1 :: FilePath -> IO Bool
isEmpty1 fp = do
stat <- getFileStatus fp
return (fileSize stat == 0)
如果需要Windows兼容性,則可以安裝提供跨平台版本的getFileStatus
的unix-compat
軟件包,也可以使用System.IO
hFileSize
:
import System.IO
isEmpty2 :: FilePath -> IO Bool
isEmpty2 fp = do
sz <- withFile fp ReadMode hFileSize
return (sz == 0)
上面的isEmpty1
的主要優點是getFileStatus
應該非常高效,因為它僅使用一個系統調用(一個stat
調用)。 如果您必須檢查大量文件的大小,這將是首選方法。 isEmpty2
解決方案也可以,但是它涉及(至少)三個系統調用( open
, fstat
,然后close
),並且需要臨時打開文件句柄,如果您在其中檢查了很多文件,可能會出現問題。並行或類似的東西。
兩者的性能都優於readFile
方法,因為它們不會導致讀取任何文件數據。 相反, readFile
需要從磁盤讀取至少一個數據塊,以確定結果字符串為空。
多虧Haskell的惰性I / O,它才可以進行初始讀取,而不必讀取整個文件,但這會導致另一個奇怪的問題。 readFile
旨在打開文件並延遲讀取其內容的方式,結果表明文件一直保持打開狀態,直到完成讀取內容為止,沒有其他方法可以強制文件在不讀取完整內容的情況下關閉! 因此,除非文件足夠短,以至於在初次讀取之前已被文件完全讀取,否則文件句柄將無限期保持打開狀態。 因此,如果您有一個程序來檢查一堆文本文件是否為空,或者如果其中一些大於單個塊,那么您可能最終會耗盡文件句柄。
通常,除非(a)將處理整個文件內容,否則不應該使用readFile
; 或(b)該程序將在讀取所需的任何部分內容后立即終止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.