Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error reading and writing same file simultaneously in Haskell

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?

like image 206
Rogach Avatar asked Oct 27 '12 05:10

Rogach


1 Answers

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.

like image 150
Dietrich Epp Avatar answered Sep 23 '22 15:09

Dietrich Epp