Error reading and writing same file simultaneously in Haskell

742 views Asked by At

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?

1

There are 1 answers

17
Dietrich Epp On BEST ANSWER

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.

Lazy IO

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.