簡體   English   中英

如何檢查Haskell中的文本文件是否為空?

[英]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表達式返回與xy類型相同的值-在這里, xy都具有IO ()類型,因此該表達式返回IO () ,即為什么可以在此do塊中使用它。


請注意,這不會檢查文件是否為空,而是會檢查標准輸入是否為空:如果將文件中的輸入管道傳輸到程序的stdin中就可以了,但是如果您想實際讀取文件,則應該查看readFile您幾乎不需要更改此程序! 像下面這樣的東西可以解決問題:

main = do
   putStrLn "Enter the file path:"
   path <- getLine
   contents <- readFile path
   if null contents ...

@hnefatl的答案很好,這可能就是您要使原始代碼正常工作所需要的。 但是,如果其他人在試圖弄清楚如何檢查文件是否為空時偶然發現了這個問題,則會給出更高級(但更可取)的答案。

在“真實” Haskell代碼,假設你嘗試檢查一個純文本文件的大小,你可能會使用getFileStatus和輔助功能, fileSizeSystem.Posix ,在這個問題討論: 什么是檢索的最佳方式haskell中文件的大小?

具體來說,類似以下功能的功能將在Linux上運行:

import System.Posix

isEmpty1 :: FilePath -> IO Bool
isEmpty1 fp = do
  stat <- getFileStatus fp
  return (fileSize stat == 0)

如果需要Windows兼容性,則可以安裝提供跨平台版本的getFileStatusunix-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解決方案也可以,但是它涉及(至少)三個系統調用( openfstat ,然后close ),並且需要臨時打開文件句柄,如果您在其中檢查了很多文件,可能會出現問題。並行或類似的東西。

兩者的性能都優於readFile方法,因為它們不會導致讀取任何文件數據。 相反, readFile需要從磁盤讀取至少一個數據塊,以確定結果字符串為空。

多虧Haskell的惰性I / O,它才可以進行初始讀取,而不必讀取整個文件,但這會導致另一個奇怪的問題。 readFile旨在打開文件並延遲讀取其內容的方式,結果表明文件一直保持打開狀態,直到完成讀取內容為止,沒有其他方法可以強制文件在不讀取完整內容的情況下關閉! 因此,除非文件足夠短,以至於在初次讀取之前已被文件完全讀取,否則文件句柄將無限期保持打開狀態。 因此,如果您有一個程序來檢查一堆文本文件是否為空,或者如果其中一些大於單個塊,那么您可能最終會耗盡文件句柄。

通常,除非(a)將處理整個文件內容,否則不應該使用readFile 或(b)該程序將在讀取所需的任何部分內容后立即終止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM