File 如何使用Haskell拆分110Mo文件
我有一个文件,看起来像File 如何使用Haskell拆分110Mo文件,file,haskell,file-io,io,File,Haskell,File Io,Io,我有一个文件,看起来像index:label,索引的值包含0范围内的键。。。100000000和标签可以是任何字符串值,我想分割这个文件,它在100行的多个切片中有110个Mo,并在每个切片上进行一些计算。我该怎么做 123 : "acgbdv" 127 : "ytehdh" 129 : "yhdhgdt" ... 9898657 : "bdggdggd" 如果您使用的是字符串IO,则可以执行以下操作: import System.IO import Control.Monad --
index:label
,索引的值包含0范围内的键。。。100000000
和标签可以是任何字符串
值,我想分割这个文件,它在100行的多个切片中有110个Mo,并在每个切片上进行一些计算。我该怎么做
123 : "acgbdv"
127 : "ytehdh"
129 : "yhdhgdt"
...
9898657 : "bdggdggd"
如果您使用的是字符串IO,则可以执行以下操作:
import System.IO
import Control.Monad
-- | Process 100 lines
process100 :: [String] -> MyData
-- whatever this function does
loop :: [String] -> [MyData]
loop lns = go [] lns
where
go acc [] = reverse acc
go acc lns = let (this, next) = splitAt 100 lns in go (process100 this:acc) next
processFile :: FilePath -> IO [MyData]
processFile f = withFile f ReadMode (fmap (loop . lines) . hGetContents)
请注意,此函数将以静默方式处理最后一个块,即使它不是100行
bytestring和text等包通常提供行
和hGetContents
等功能,因此您应该能够轻松地将此功能调整到其中任何一个
了解处理每个切片的结果时所做的工作是很重要的,因为您不希望保留该数据超过必要的时间。理想情况下,在计算每个切片之后,数据将被完全消耗,并且可以进行gc。通常,要么将单独的结果组合成一个数据结构(“折叠”),要么单独处理每个结果(可能将一行输出到文件或类似的内容)。如果是折叠,则应将“循环”更改为如下所示:
loopFold :: [String] -> MyData -- assuming there is a Monoid instance for MyData
loopFold lns = go mzero lns
where
go !acc [] = acc
go !acc lns = let (this, next) = splitAt 100 lns in go (process100 this `mappend` acc) next
loopFold
函数使用bang模式(通过“LANGUAGE BangPatterns”pragma启用)强制计算“MyData”。根据MyData是什么,您可能需要使用deepseq
,以确保对其进行全面评估
如果您要将每一行写入输出,请保持loop
不变,并更改processFile
:
processFileMapping :: FilePath -> IO ()
processFileMapping f = withFile f ReadMode pf
where
pf = mapM_ (putStrLn . show) <=< fmap (loop . lines) . hGetContents
processFileMapping::FilePath->IO()
processFileMapping f=withFile f ReadMode pf
哪里
pf=mapM(putStrLn.show)它在法语中相当于“MB”-兆八位组。