我必须解决以下问题。
有很多文件可以说例如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。
如何编写程序以检索每个文件中的行并显示我的匹配项,然后再转到文件中的以下行。这当然会避免加载所有文件并充分利用垃圾收集器?
个人资料图片
抱歉,我不知道如何在这里插入图片,它总是失败,但在分析时,内存使用看起来像从上到下的楼梯
好的,它有效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)
再次感谢
答案 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'
虽然没有经过测试,但它应该对记忆有好处。