如何在 Haskell 中高效地写入大文件
How to write big file efficiently in Haskell
你好,我正在尝试及时 manner.Is 编写一个 ~1GB
文件,有任何推荐 method.Up 直到现在这个过程大约需要几十分钟。我使用 Text
是不是错了,我应该使用 ByteString
吗? (我也用过String
)
pt="d:\data2.csv"
cnt=400000000
main::IO()
main=do
let payload=dat
writeWithHandle pt dat
dat::Text
dat=Data.Text.pack "0744442339"
writeWithHandle::FilePath->Text->IO()
writeWithHandle path tx=do
handle<-openFile path WriteMode
writeTimes cnt handle dat
writeTimes::Int->Handle->Text->IO()
writeTimes cnt handle payload= forM_ ([0..cnt]) (\x->Data.Text.IO.hPutStrLn handle payload)
我不明白为什么我用的是 minutes.Initially 的 writeFile
,但我认为这意味着要不断地打开和关闭 file
对于每一行,所以我使用 appendFile
无济于事。
我建议为此使用生成器,这是填充缓冲区的有效方法,并且可以直接写入句柄。
#!/usr/bin/env stack
-- stack --resolver ghc-8.6.4 script
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Builder (Builder, hPutBuilder)
import Data.Foldable (fold)
import System.IO (IOMode (WriteMode), withBinaryFile)
pt :: FilePath
pt = "data2.csv"
cnt :: Int
cnt = 400000000
main :: IO ()
main = writeWithHandle pt dat
dat :: Builder
dat = "0744442339"
writeWithHandle :: FilePath -> Builder -> IO ()
writeWithHandle path tx =
withBinaryFile path WriteMode $ \h ->
hPutBuilder h $ makeBuilder cnt tx
makeBuilder :: Int -> Builder -> Builder
makeBuilder cnt payload = fold $ replicate cnt $ payload <> "\n"
如果愿意,您可以将 payload
保留为 Text
值,然后使用 encodeUtf8Builder
.
转换为 Builder
你好,我正在尝试及时 manner.Is 编写一个 ~1GB
文件,有任何推荐 method.Up 直到现在这个过程大约需要几十分钟。我使用 Text
是不是错了,我应该使用 ByteString
吗? (我也用过String
)
pt="d:\data2.csv"
cnt=400000000
main::IO()
main=do
let payload=dat
writeWithHandle pt dat
dat::Text
dat=Data.Text.pack "0744442339"
writeWithHandle::FilePath->Text->IO()
writeWithHandle path tx=do
handle<-openFile path WriteMode
writeTimes cnt handle dat
writeTimes::Int->Handle->Text->IO()
writeTimes cnt handle payload= forM_ ([0..cnt]) (\x->Data.Text.IO.hPutStrLn handle payload)
我不明白为什么我用的是 minutes.Initially 的 writeFile
,但我认为这意味着要不断地打开和关闭 file
对于每一行,所以我使用 appendFile
无济于事。
我建议为此使用生成器,这是填充缓冲区的有效方法,并且可以直接写入句柄。
#!/usr/bin/env stack
-- stack --resolver ghc-8.6.4 script
{-# LANGUAGE OverloadedStrings #-}
import Data.ByteString.Builder (Builder, hPutBuilder)
import Data.Foldable (fold)
import System.IO (IOMode (WriteMode), withBinaryFile)
pt :: FilePath
pt = "data2.csv"
cnt :: Int
cnt = 400000000
main :: IO ()
main = writeWithHandle pt dat
dat :: Builder
dat = "0744442339"
writeWithHandle :: FilePath -> Builder -> IO ()
writeWithHandle path tx =
withBinaryFile path WriteMode $ \h ->
hPutBuilder h $ makeBuilder cnt tx
makeBuilder :: Int -> Builder -> Builder
makeBuilder cnt payload = fold $ replicate cnt $ payload <> "\n"
如果愿意,您可以将 payload
保留为 Text
值,然后使用 encodeUtf8Builder
.
Builder