Sté*_*ent 6 haskell network-drive lazy-evaluation
考虑以下简单的Haskell程序,该程序将文件作为字节串读取并tmp.tmp从该字节串写入文件:
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"
Run Code Online (Sandbox Code Playgroud)
它被编译为名为的可执行文件tmptmp.
我的计算机上有两个硬盘驱动器:C驱动器和U驱动器,这个是网络驱动器,此网络驱动器处于脱机状态.
现在,让我们试试吧tmptmp.
当我运行它时C,没有问题; 我在下面运行两次,第一次打开文件,C第二次打开文件U:
C:\HaskellProjects\imagelength> tmptmp LICENSE
done
C:\HaskellProjects\imagelength> tmptmp U:\Data\ztemp\test.xlsx
done
Run Code Online (Sandbox Code Playgroud)
现在我U用C驱动器上的文件运行它,没问题:
U:\Data\ztemp> tmptmp C:\HaskellProjects\imagelength\LICENSE
done
Run Code Online (Sandbox Code Playgroud)
当我使用驱动器上的文件运行它UU时会发生此问题:
U:\Data\ztemp> tmptmp test.xlsx
tmptmp: tmp.tmp: openBinaryFile: resource busy (file is locked)
Run Code Online (Sandbox Code Playgroud)
如果我的节目,我用严格的字节串,而不是懒惰的字节串(替换Data.ByteString.Lazy用Data.ByteString),不会再出现此问题.
我想明白这一点.任何解释?(我特别想知道如何解决这个问题,但仍然使用延迟字节串)
或许更精确一点,这个程序仍然会出现问题:
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"
Run Code Online (Sandbox Code Playgroud)
而问题消失了:
bs <- SB.readFile file
action <- LB.writeFile "tmp.tmp" (LB.fromStrict bs)
Run Code Online (Sandbox Code Playgroud)
看起来引起问题的一点是懒惰readFile.
小智 0
根据最新的Data.ByteString.Lazy 文档:
\n\n\n使用 readFile 或 hGetContents 等惰性 I/O 函数意味着关闭文件句柄等操作的顺序由 RTS 自行决定。
\n
给出的脱机网络驱动器示例可能会导致 RTS 从 readFile 继续,而不关闭文件。该文档有一个几乎相同的例子,说
\n\n\n当接下来执行 writeFile 时,[tmp.tmp] 仍然打开以供读取,并且 RTS 会注意避免同时打开它进行写入,而是返回错误。
\n
据我所知, Data.ByteString.Lazy \xe2\x80\x94 中没有解决方案,文档上建议了您的解决方案(使用严格读取)和其他包。有时读取和写入同一个文件可以工作,但你不能保证。
\n| 归档时间: |
|
| 查看次数: |
686 次 |
| 最近记录: |