gpt4 book ai didi

file - 如何在haskell中关闭文件

转载 作者:行者123 更新时间:2023-12-05 01:35:44 27 4
gpt4 key购买 nike

我对 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:资源繁忙(文件被锁定)”。我该如何解决这个问题?有人告诉我,出现这种情况是因为我没有关闭该文件。但我该如何关闭它呢?

最佳答案

函数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"

解决方案 2(临时修复)

您还可以通过确保在写入文件之前评估整个文件内容来防止出现此问题。然后,文件将在您开始写入之前读取后关闭。有几种方法可以做到这一点。这是一个:

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 的全部内容此时进行评估。

关于file - 如何在haskell中关闭文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22166912/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com