我可以在Haskell中同时处理许多文件吗?

时间:2010-09-24 22:49:35

标签: haskell file garbage-collection

我必须解决以下问题。

有很多文件可以说例如3,其中包含以下内容

文件1

A1

A2

A3

A4

A5

A6

...

file2的

B1

B2

B3

B4

B5

B6

...

file3的

C1

C2

C3

C4

C5

C6

...

我的程序必须在参数中获取文件名,读取这些文件并打印以下结果

“a1​​ b1 c1”

“a2 b2 c2”

“a3 b3 c3”

“a4 b4 c4”

“a5 b5 c5”

“a6 b6 c6”

...

我已经编写了一个版本的程序,但它首先阅读所有文件,这非常有用,因为这些文件的大小可能是200Mb。

如何编写程序以检索每个文件中的行并显示我的匹配项,然后再转到文件中的以下行。这当然会避免加载所有文件并充分利用垃圾收集器?

个人资料图片

抱歉,我不知道如何在这里插入图片,它总是失败,但在分析时,内存使用看起来像从上到下的楼梯

alt text

好的,它有效1

感谢回复

答案

感谢FUZxxi他的回答真的对我很有帮助,但是当文件没有相同数量的行时出现了问题,为了解决这个问题,我以这种方式重写了他的程序

printLines :: [[String]] -> IO ()

printLines [] = return ()

printLines ss = do

    ss' <- printFirstLine ss

    if and $ map null ss' then putStrLn "finish" else printLines ss'





printFiles :: [FilePath] -> IO ()

printFiles paths = do

  files <- mapM readFile paths

  let fileLines = map lines files

  printLines fileLines



sliceFirstRow :: [[String]] -> ([String],[[String]])

sliceFirstRow list = unzip $ map getFirst list



printFirstLine :: [[String]] -> IO ([[String]])

printFirstLine ss = do

  let (fline,lline) = sliceFirstRow ss

  mapM_ putStrLn fline

  return lline    



getFirst :: [String] -> (String, [String])

getFirst [] = ("",[])

getFirst (x:xs) = (x,xs)

再次感谢

1 个答案:

答案 0 :(得分:2)

我会做这样的事情:

printFiles :: [FilePath] -> IO ()
printFiles paths= do
  files <- mapM readFile paths
  let fileLines = map lines files
  printLines fileLines
  where
  sliceFirstRow :: [[String]] -> ([String],[[String]])
  sliceFirstRow list = unzip $ map helper list where
    helper (x:xs) = (x,xs)
    helper []     = "" -- Your behaviour here
  printFirstLine :: [[String]] -> IO ([[String]])
  printFirstLine ss = do
    let (fline,lline) = sliceFirstRow ss
    mapM_ putStrLn fline
    return lline
  printLines :: [[String]] -> IO ()
  printLines [] = return ()
  printLines ss = do
    ss' <- printFirstLine ss
    printLines ss'

虽然没有经过测试,但它应该对记忆有好处。