2016-08-13 13 views
5

Thiết lậpLàm cách nào bạn duyệt qua một thư mục và thực hiện một số chức năng trên tất cả các tệp và kết hợp đầu ra theo cách hiệu quả của bộ nhớ?

Tôi cần duyệt qua thư mục trên 100 tệp .txt, mở mỗi thư mục và thực hiện một số chức năng trên mỗi tệp, sau đó kết hợp kết quả. Các tệp này rất lớn, theo thứ tự 10GB. Một số hoạt động phổ biến ở psuedocode có thể là:

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

Bí quyết là để đảm bảo tất cả các tập tin không bao giờ tồn tại trong bộ nhớ cùng một lúc, giải pháp ngây thơ trước đây của tôi đã tạo ra tất cả các loại file swap trên mac của tôi. Ngoài ra, nếu một trong tệp filePath không hợp lệ, tôi chỉ muốn bỏ qua và tiếp tục với chương trình.

Giải pháp của tôi

Hiện nay tôi đang sử dụng ống dẫn và muốn tìm một giải pháp sử dụng ống dẫn nếu có thể. Nhưng nếu nó không phải là công cụ thích hợp tôi sử dụng cái gì khác.

Trả lời

3

Bạn có thể tổ ống dẫn thực hiện như thế này:

{-# 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) 

Thay processFile với bất cứ điều gì bạn muốn làm - bao gồm bỏ qua các tập tin. Sự hiểu biết của tôi là Nhà sản xuất sourceFile sẽ chẻ một cách hiệu quả nội dung của một tệp.

Và, theo số this Yesod article, sourceDirectoryDeep nên xem qua cấu trúc thư mục hiệu quả.

Điều bạn dường như không thể thực hiện với sourceDirectoryDeep là các thư mục tỉa .

+1

Trừ khi thư mục có số lượng tệp khổng lồ thực sự, một máy lạ mắt nghe có vẻ quá mức cần thiết. Làm thế nào về việc chỉ đọc thư mục, sau đó sử dụng 'foldM' để xử lý từng thư mục, kết hợp các kết quả trên đường đi? – dfeuer

+0

Không biết OP có cần hay không, nhưng 'sourceDirectoryDeep' thực hiện truyền tải đệ quy. Nhưng có, hiệu quả lớn hơn sẽ đến từ việc xử lý nội dung của mỗi tập tin theo kiểu chunked. – ErikR

+2

@dfeuer ống dẫn (hoặc ống dẫn) 'foldM' là * thậm chí không * hơi phức tạp hơn' Control.Monad.foldM'. Số lượng tuyệt vời của thảm họa có thể xảy ra bằng cách làm việc với một danh sách các Filepaths lười biếng phát triển từ một traversal thư mục là một trong những trẻ em poster ban đầu cho streaming io. Nó * chỉ đơn giản là không * và không nên được khuyến khích. 'Import Conduit' ngắn hơn' Import.Monad' nhập khẩu, và một khi bạn gõ nó, bạn có cả cây thư mục và hàm fold đúng để áp dụng cho nó. – Michael

Các vấn đề liên quan