I need to modify a file in-place. So I planned to read file contents, process them, then write the output to the same file:
main = do
input <- readFile "file.txt"
let output = (map toUpper input)
-- putStrLn $ show $ length output
writeFile "file.txt" output
But the problem is, it works as expected only if I uncomment the 4th line - where I just output number of characters to console. If I don't uncomment it, I get
openFile: resource busy (file is locked)
Is there a way to force reading of that file?
The simplest thing might be strict ByteString
IO:
import qualified Data.ByteString.Char8 as B
main = do
input <- B.readFile "file.txt"
B.writeFile "file.txt" $ B.map toUpper input
As you can see, it's the same code -- but with some functions replaced with ByteString
versions.
The problem that you're running into is that some of Haskell's IO functions use "Lazy IO", which has surprising semantics. In almost every program I would avoid lazy IO.
These days, people are looking for replacements to Lazy IO like Conduit and the like, and lazy IO is seen as an ugly hack which unfortunately is stuck in the standard library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With