Consider the following simple Haskell program, which reads a file as a byte string and writes the tmp.tmp file from this byte:
module Main where import System.Environment import qualified Data.ByteString.Lazy as B main :: IO () main = do [file] <- getArgs bs <- B.readFile file action <- B.writeFile "tmp.tmp" bs putStrLn "done"
It is compiled into an executable file called tmptmp .
I have two hard drives on my computer: drive C and drive U , and this one is a network drive, and this network drive is offline.
Now try tmptmp .
When I run it from C , there is no problem; I run it two times lower, the first time with a file in C , and the second time with a file in U :
C:\HaskellProjects\imagelength> tmptmp LICENSE done C:\HaskellProjects\imagelength> tmptmp U:\Data\ztemp\test.xlsx done
Now I run it from U , with a file on drive C , no problem:
U:\Data\ztemp> tmptmp C:\HaskellProjects\imagelength\LICENSE done
The problem occurs when I run it from U with a file on U disk:
U:\Data\ztemp> tmptmp test.xlsx tmptmp: tmp.tmp: openBinaryFile: resource busy (file is locked)
If in my program I use strict bytes rather than lazy bytes (replacing Data.ByteString.Lazy with Data.ByteString ), this problem no longer occurs.
I would like to understand that. Any explanation? (I would especially like to know how to solve this problem, but still use lazy bytes)
EDIT
To be more precise, a problem still arises with this program:
import qualified Data.ByteString as SB import qualified Data.ByteString.Lazy as LB main :: IO () main = do [file] <- getArgs bs <- LB.readFile file action <- SB.writeFile "tmp.tmp" (LB.toStrict bs) putStrLn "done"
while the problem disappears with:
bs <- SB.readFile file action <- LB.writeFile "tmp.tmp" (LB.fromStrict bs)
It seems that the cause of the problem is readFile laziness.