作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 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"
您还可以通过确保在写入文件之前评估整个文件内容来防止出现此问题。然后,文件将在您开始写入之前读取后关闭。有几种方法可以做到这一点。这是一个:
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/
我是一名优秀的程序员,十分优秀!