6

环境

我需要遍历一个超过 100 多个 .txt 文件的目录,打开每个文件并对每个文件执行一些功能,然后组合结果。这些文件很大,大约 10GB。伪代码中的一些常见操作可能是:

foldr concatFile mempty $ openFile <$> [filePath1, ..., filePathn]
foldr countStuff 0      $ openFile <$> [filePath1, ..., filePathn]

诀窍是确保所有文件永远不会同时存在于内存中,我之前的天真的解决方案在我的 Mac 上创建了各种交换文件。此外,如果其中一个 filePath 无效,我想跳过它并继续执行该程序。

我的解决方案

目前我正在使用管道,如果可能的话,我想找到一个使用管道的解决方案。但如果它不是正确的工具,我可以使用其他工具。

4

1 回答 1

4

您可以像这样嵌套管道执行:

{-# LANGUAGE OverloadedStrings #-}

import Conduit
import qualified Data.ByteString as BS

-- Process a single file
processFile :: FilePath -> IO ()
processFile path = runResourceT (sourceFile path =$= mapC BS.length $$ sumC) >>= print

-- Run processFile for directory in a tree    
doit :: FilePath -> IO ()
doit top = runResourceT $ sourceDirectoryDeep False top $$ mapM_C (liftIO . processFile)

替换processFile为您想做的任何事情——包括忽略文件。我的理解是sourceFileProducer 将有效地分块文件的内容。

而且,根据这篇 Yesod 文章sourceDirectoryDeep应该有效地遍历目录结构。

您显然不能做的事情sourceDirectoryDeep是修剪目录。

于 2016-08-13T21:19:10.243 回答