在Haskell中同时读取和写入同一文件时出错

Rog*_*ach 5 file-io haskell locking lazy-evaluation lazy-io

我需要就地修改文件.所以我打算读取文件内容,处理它们,然后将输出写入同一个文件:

main = do
  input <- readFile "file.txt"
  let output = (map toUpper input) 
  -- putStrLn $ show $ length output
  writeFile "file.txt" output
Run Code Online (Sandbox Code Playgroud)

但问题是,只有当我取消注释第4行时才会按预期工作 - 我只是输出字符数到控制台.如果我不取消注释,我会得到

openFile: resource busy (file is locked)
Run Code Online (Sandbox Code Playgroud)

有没有办法强制阅读该文件?

Die*_*Epp 5

最简单的事情可能是严格的ByteStringIO:

import qualified Data.ByteString.Char8 as B

main = do
  input <- B.readFile "file.txt"
  B.writeFile "file.txt" $ B.map toUpper input
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它是相同的代码 - 但某些功能已被ByteString版本替换.

懒惰的IO

您遇到的问题是Haskell的一些IO函数使用"Lazy IO",它具有令人惊讶的语义.在几乎每个程序中,我都会避免懒惰的IO.

现在,人们正在寻找像管道之类的懒惰IO的替代品,懒惰的IO被视为丑陋的黑客,遗憾的是它被困在标准库中.

  • Rogach,怎么样`input < - fmap Data.Text.unpack $ Data.Text.IO.readFile"file.txt"`这里`input`是一个延迟生成的字符串,但它来自一个完全评估的Text值,所以块的其余部分可以如上继续.这可能比使用bytestring更加人性化...... (2认同)