2016-08-13 4 views
5

स्थापनाआप किसी निर्देशिका को कैसे पार करेंगे और सभी फ़ाइलों पर कुछ फ़ंक्शन करें और आउटपुट को मेमोरी कुशल तरीके से गठबंधन करें?

मैं 100 + .txt फ़ाइलें पर एक निर्देशिका पार करने के लिए की जरूरत है, खुला हर एक और, प्रत्येक पर कुछ समारोह कर तो गठबंधन का परिणाम है। 10 जीबी के क्रम में ये फ़ाइलें बड़ी हैं। psuedocode में कुछ सामान्य ऑपरेशन हो सकता है:

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

चाल यकीन है कि सभी फाइलों को एक ही समय में स्मृति में मौजूद कभी नहीं करना है, मेरे पिछले अनुभवहीन समाधान पर अपने मैक स्वैप फ़ाइलों के सभी प्रकार का निर्माण किया। इसके अलावा, यदि FilePath में से एक अमान्य है, मैं सिर्फ यह से अधिक छोड़ सकते हैं और कार्यक्रम के साथ पर जाने के लिए चाहते हैं।

मेरे समाधान

वर्तमान में मैं नाली का उपयोग कर रहा है और एक समाधान यदि संभव हो तो नाली का उपयोग कर प्राप्त करना चाहते हैं। लेकिन अगर यह सही उपकरण नहीं है तो मैं कुछ और उपयोग करने के साथ ठीक हूं।

उत्तर

3

आप इस तरह घोंसला नाली निष्पादन कर सकते हैं:

{-# 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 - फ़ाइल अनदेखी भी शामिल है। मेरी समझ है कि sourceFile निर्माता कुशलतापूर्वक होगा हिस्सा एक फ़ाइल की सामग्री।

और, this Yesod article के अनुसार, sourceDirectoryDeep कुशलता से एक निर्देशिका संरचना पार करना चाहिए।

जो चीज आप स्पष्ट रूप से sourceDirectoryDeep के साथ नहीं कर सकते हैं वह prune निर्देशिका है।

+1

जब तक निर्देशिका फ़ाइलों की एक सही मायने में जबरदस्त संख्या है, एक कल्पना मशीन overkill की तरह लगता है। निर्देशिका को पढ़ने के बारे में, फिर प्रत्येक को संसाधित करने के लिए 'foldM' का उपयोग करके, परिणामों के साथ संयोजन का संयोजन कैसे करें? – dfeuer

+0

पता नहीं है कि ओपी को इसकी आवश्यकता है, लेकिन 'SourceDirectoryDeep' एक रिकर्सिव ट्रैवर्सल करता है। लेकिन हां, बड़ी दक्षता प्रत्येक फ़ाइल की सामग्री को एक खंडित फैशन में संसाधित करने से आती है। – ErikR

+2

@dfeuer नाली (या पाइप) 'foldM' *' Control.Monad.foldM' तुलना में अधिक जटिल है नहीं भी थोड़ा *। एक निर्देशिका ट्रैवर्सल से विकसित फ़ाइलपैथ की सूची के साथ काम करके होने वाली आपदाओं की अद्भुत संख्या आईओ स्ट्रीमिंग के लिए मूल पोस्टर बच्चों में से एक थी। यह * बस आसान नहीं है * और सिफारिश नहीं की जानी चाहिए। 'आयात कंडिट 'आयात नियंत्रण' मोनाड 'से छोटा है, और एक बार जब आप इसे लिखते हैं, तो आपके पास निर्देशिका पेड़ और सही फोल्ड फ़ंक्शन दोनों पर लागू होते हैं। – Michael

संबंधित मुद्दे