Я пытаюсь работать с большими файлами, используя Haskell. Я хотел бы просмотреть байт за байтом входного файла и сгенерировать выходной байт за байтом. Конечно, мне нужно, чтобы IO буферизовался блоками разумного размера (несколько КБ). Я не могу этого сделать, и мне нужна ваша помощь, пожалуйста.
import System
import qualified Data.ByteString.Lazy as BL
import Data.Word
import Data.List
main :: IO ()
main =
do
args <- System.getArgs
let filename = head args
byteString <- BL.readFile filename
let wordsList = BL.unpack byteString
let foldFun acc word = doSomeStuff word : acc
let wordsListCopy = foldl' foldFun [] wordsList
let byteStringCopy = BL.pack (reverse wordsListCopy)
BL.writeFile (filename ++ ".cpy") byteStringCopy
where
doSomeStuff = id
Я называю этот файл TestCopy.hs
, а затем делаю следующее:
$ ls -l *MB
-rwxrwxrwx 1 root root 10000000 2011-03-24 13:11 10MB
-rwxrwxrwx 1 root root 5000000 2011-03-24 13:31 5MB
$ ghc --make -O TestCopy.hs
[1 of 1] Compiling Main ( TestCopy.hs, TestCopy.o )
Linking TestCopy ...
$ time ./TestCopy 5MB
real 0m5.631s
user 0m1.972s
sys 0m2.488s
$ diff 5MB 5MB.cpy
$ time ./TestCopy 10MB
real 3m6.671s
user 0m3.404s
sys 1m21.649s
$ diff 10MB 10MB.cpy
$ time ./TestCopy 10MB +RTS -K500M -RTS
real 2m50.261s
user 0m3.808s
sys 1m13.849s
$ diff 10MB 10MB.cpy
$
Моя проблема: Существует огромная разница между файлом размером 5 и 10 МБ. Я бы хотел, чтобы выступления были линейными по размеру входного файла. Пожалуйста, что я делаю не так и как мне этого добиться? Я не против использования ленивых строк байтов или чего-то еще, пока это работает, но это должна быть стандартная библиотека ghc.
Точность: это для университетского проекта. И я не пытаюсь копировать файлы. Функция doSomeStuff
должна выполнять действия сжатия / распаковки, которые я должен настроить.