Рассмотрим следующую простую программу на 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"
Он скомпилирован в исполняемый файл с именем tmptmp
.
У меня на компьютере два жестких диска: диск C
и диск U
, и этот диск является сетевым, и этот сетевой диск отключен.
Теперь попробуем tmptmp
.
Когда я запускаю его из C
, проблем нет; Я запускаю его два раза ниже, первый раз с файлом на C
и второй раз с файлом на U
:
C:\HaskellProjects\imagelength> tmptmp LICENSE
done
C:\HaskellProjects\imagelength> tmptmp U:\Data\ztemp\test.xlsx
done
Сейчас запускаю с U
, с файлом на C
диске, проблем нет:
U:\Data\ztemp> tmptmp C:\HaskellProjects\imagelength\LICENSE
done
Проблема возникает, когда я запускаю ее из U
с файлом на U
диске:
U:\Data\ztemp> tmptmp test.xlsx
tmptmp: tmp.tmp: openBinaryFile: resource busy (file is locked)
Если в моей программе я использую строгие строки байтов вместо ленивых строк байтов (путем замены 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"
пока проблема исчезает с:
bs <- SB.readFile file
action <- LB.writeFile "tmp.tmp" (LB.fromStrict bs)
Похоже, проблема в лени readFile
.
BS
? Кажется, вы обнаружили, чтоStrict
правильный инструмент для работы 4. Работает ли это, если вы принудительно вводите (т.е.evaluate (length bs)
перед записью)? - person user2407038   schedule 17.06.2017xlsx
, которая работает с ленивыми строками байтов. 4) Функциюevaluate
не знал, попробую. - person Stéphane Laurent   schedule 17.06.2017LB.readFile
, затемfromStrict
. Но очевидно, что это не дает объяснения. - person Stéphane Laurent   schedule 17.06.2017file.access
R
, дискU
недоступен для записи (пока он доступен для записи). Но было бы странно, чтоU
распознается как недоступное для записи только тогда, когда я использую ленивую строку байтов. - person Stéphane Laurent   schedule 18.06.2017getPermissions
изSystem.Directory
:getPermissions "U:/Data"
указывает, чтоU:/Data
недоступно для записи... хм, но, тем не менее, указывает, чтоU:/Data/zTemp
доступно для записи. - person Stéphane Laurent   schedule 18.06.2017