2009-12-28 15 views
5

यहाँ कोड मैं का उपयोग कर रहा है। इन निर्देशिकाओं में कभी-कभी 2 मिलियन फाइलें होती हैं।सी # directory.getfiles स्मृति मदद

यह चल रहा है, इस प्रक्रिया की निगरानी में मैंने इसे 800 एमबी मेमोरी उपयोग पर चढ़ाया है। क्या कोई तरीका है कि मैं इस प्रक्रिया की गति को संरक्षित कर सकता हूं और इसका उपयोग करने वाली स्मृति को सीमित कर सकता हूं? या यह पढ़ा है और डंप और जारी है? हैश टेबल? कोई विचार अद्भुत होगा।

+0

800K? क्या आपका मतलब 800 एमबी था? –

+1

मेमोरी उपयोग की 1 एमबी क्यों समस्या है?एक लाख से अधिक फाइलें? –

+0

800 मेग्स जो मैं –

उत्तर

14

निर्देशिका। गेटफाइल वास्तव में बेकार है। यदि आप .NET 4.0 का उपयोग कर सकते हैं तो आपको Directory.EnumerateFiles का उपयोग करना चाहिए। डॉक्स से:

EnumerateFiles और GetFiles तरीके इस प्रकार अलग: जब आप उपयोग EnumerateFiles, आप नाम के संग्रह की गणना से पहले पूरे संग्रह लौटे है शुरू कर सकते हैं; जब आप GetFiles का उपयोग करते हैं, तो आप को सरणी का उपयोग करने से पहले वापस आने के लिए नामों की पूरी सरणी का इंतजार करना होगा। इसलिए, जब आप कई फ़ाइलों और निर्देशिकाओं के साथ काम कर रहे हैं, तो EnumerateFiles अधिक कुशल हो सकती है।

+0

मुझे नहीं पता था कि वे इसे जोड़ रहे थे। अच्छा! – BFree

+0

@ बीएफरी- यह निश्चित रूप से अच्छा है! यह .NET 4.0 में चीजों में से एक है, मैं उम्मीद कर रहा हूं! – RichardOD

+0

मेरा मानना ​​है कि नेट के मोनो कार्यान्वयन में यह भी है, इसलिए यदि आप .NET 4 विकल्प नहीं हैं तो आप फ़ाइलों पर पुनरावृत्ति के लिए मोनो libs का उपयोग कर सकते हैं। –

0

का उपयोग के रूप में जवाब here यदि .NET 4.0 का उपयोग कर, आप निर्देशिका वर्ग पर स्थिर EnumerateFiles विधि का उपयोग कर सकते हैं के बजाय एक IEnumerable<string> प्राप्त करने के लिए उल्लेख किया है का सुझाव एक स्ट्रिंग [], जो सभी मेमोरी खपत का कारण बन रही है।

यदि आप .NET 4.0 से पहले .NET के संस्करण के साथ काम कर रहे हैं, तो आप P/Invoke परत के माध्यम से FindFirstFileEx, FindNextFile, आदि, विधियों को कॉल करके आसानी से इस कार्यक्षमता की नकल कर सकते हैं।

फिर, कॉल से लौटाई गई प्रत्येक फ़ाइल के लिए FindFirstFile/FindNextFile आप आइटम को वापस लाएंगे।

यह मेमोरी खपत पर कटौती करेगा क्योंकि एन्युमरेटफाइल बड़ी संख्या में फाइलों के साथ निर्देशिकाओं के लिए होगा क्योंकि आप उन्हें सभी को एक सरणी में लोड नहीं कर रहे हैं, लेकिन उन्हें प्रसंस्करण के लिए उन्हें उपज के रूप में उपलब्ध करा रहे हैं।

1

यदि आप Fx4 का उपयोग नहीं कर सकते हैं तो आप अपना स्वयं का फ़ाइलइनेमेटर लिखना चाहते हैं। यहां one example है।

+0

+1। मैं इस तरह कुछ विकल्प के रूप में सुझाव देने जा रहा था। मुझे लगता है कि कोडप्रोजेक्ट में कुछ समान है। – RichardOD

1

Directory.GetFiles को वापस आने से पहले सभी मिलान करने वाली फ़ाइलों की एक सूची बनाना है। केवल तभी आप उन्हें गिन सकते हैं। तो निश्चित रूप से, यह बहुत महंगा है जब बहुत सारी मेल खाने वाली फाइलें हैं। यह आंतरिक रूप से सभी फाइलों की एक सूची भी बना सकता है।

यदि आप .NET 4.0 का उपयोग कर सकते हैं, तो आप Directory.EnumerateFiles का उपयोग कर सकते हैं जो एक समय में एक फ़ाइल को पुनर्प्राप्त करके इस समस्या से बचाता है। यदि आप नहीं कर सकते हैं, तो मैं सुझाव दूंगा कि आप इसे C#+ में सी # के बजाय लिखें।

सी ++ में आप FindFirstFile का उपयोग कर सकते हैं जो एक समय में फ़ाइलों को आपके पास भी लौटाता है।

// iterate though the files in this directory 
// 
TCHAR szWild[MAX_PATH]; 
PathCombine(szWild, masterfolders, _T("*.txt")); 

WIN32_FIND_DATA fd; 
HANDLE hFind = FindFirstFile(szWild, &fd); 
if (INVALID_HANDLE_VALUE != hFind) 
{ 
    do { 
    TCHAR szFileName[MAX_PATH]; 
    PathCombine(szFileName, masterfolders, fd.cFileName); 

    // write szFilename to output stream.. 

    } while (FindNextFile(hFind, &fd)); 

    FindClose (hFind); 
} 
+0

इसका उपयोग क्या कर रहा है? –

+0

सुनिश्चित नहीं है कि टीसीएचएआर और WIN32_FInD-डेटा क्या उपयोग कर रहे हैं या संदर्भ हैं। –

+0

आह एन/एम इसे मिला टी/वाई –

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