我有一个haskell问题... 我在haskell中打开一个文件,之后我想在该文件中添加一些文本。
ame :: IO ()
ame = do
putStr "Enter the file name: "
name <- getLine
file <- readFile name
putStrLn "Do you want to add new records? "
question <- getLine
if question == "yes" then do
putStrLn "Enter your records:"
newRec <- getLine
file <- writeFile name (file ++ newRec)
putStrLn "a"
else
putStr "b"
这是我的代码。当我想在我的文件中添加(写入)新内容时,我收到此错误... “openFile:资源忙(文件被锁定)”。 我怎么能解决这个问题?我被告知这是因为我没有关闭文件..但我怎么能关闭它?
答案 0 :(得分:6)
函数readFile
使用了“懒惰IO”,这是Haskell语言的一个有争议的特性(注意:“懒惰IO”与“懒惰评估”不同)。
当您说file <- readFile name
时,此时实际上并未读取该文件。相反,一旦您评估结果字符串file
,就会读取该文件。扫描您的计划时,我们发现您评估file
的位置仅在此处:
file <- writeFile name (file ++ newRec)
函数writeFile
没有返回任何内容,所以你的意思可能就是这样:
writeFile name (file ++ newRec)
当您尝试编写相同的文件时,您正在阅读名为name
的文件。这就是造成文件锁定异常的原因。
只是使用适当的函数,而不是读取和写入整个文件只是为了追加一些东西:
appendFile :: FilePath -> String -> IO ()
表现得像writeFile
,但追加到最后。无需先读取文件。您的代码变为:
ame = do
putStr "Enter the file name: "
name <- getLine
putStrLn "Do you want to add new records? "
question <- getLine
if question == "yes" then do
putStrLn "Enter your records:"
newRec <- getLine
appendFile name newRec
putStrLn "a"
else
putStr "b"
您还可以通过确保在写入文件之前评估整个文件内容来防止出现此问题。然后,在开始写入之前,文件将在阅读后关闭。有几种方法可以做到这一点。这是一个:
import Control.DeepSeq
import Control.Exception
ame :: IO ()
ame = do
putStr "Enter the file name: "
name <- getLine
file <- readFile name
evaluate (force file)
putStrLn "Do you want to add new records? "
question <- getLine
if question == "yes" then do
putStrLn "Enter your records:"
newRec <- getLine
file <- writeFile name (file ++ newRec)
putStrLn "a"
else
putStr "b"
重要的新行是evaluate (force file)
,这会导致此时评估file
的全部内容。
答案 1 :(得分:0)
writeFile
返回IO()
,http://www.haskell.org/hoogle/?hoogle=writeFile
不writeFile name (file ++ newRec)
file <-
您也不需要在readFile
之后关闭文件,只需在执行openFile
后关闭文件,然后您必须执行hClose file