2010-01-13 15 views
11

जब मैं किसी निर्देशिका की फ़ाइलों को सूचीबद्ध करता हूं जिसमें जावा के साथ 300,000 फ़ाइलें हैं, तो स्मृति से बाहर होता है।आउटऑफमेमरी जब निर्देशिका में फ़ाइलों को सूचीबद्ध करता है

String[] fileNames = file.list(); 

क्या मैं चाहता हूँ एक तरीका है कि एक निर्देशिका की सभी फाइलों को संवर्द्धित कोई फर्क नहीं पड़ता है कि विशिष्ट निर्देशिका में कितने फ़ाइलें सूचीबद्ध कर सकते हैं और "स्मृति से बाहर" डिफ़ॉल्ट 64M ढेर सीमा के साथ समस्या है नहीं होगा।

मेरे पास Google थोड़ी देर है, और शुद्ध जावा में ऐसा कोई रास्ता नहीं मिल रहा है।
कृपया मेरी मदद करें !!

नोट, जेएनआई एक संभावित समाधान है, लेकिन मुझे जेएनआई से नफरत है।

+0

क्या 64 एमबी ढेर सीमा एक कठिन है? क्या आपके पास अपने कोड के अन्य भाग भी हैं जो बहुत सारी वस्तुओं को आवंटित करते हैं? – notnoop

+0

64 एमबी एक कठिन सीमा नहीं है। हालांकि, हम एक ऐसे फ़ोल्डर की निगरानी के लिए जावा का उपयोग करना चाहते हैं जिसमें हमारे ग्राहकों द्वारा बड़ी मात्रा में फाइलें अपलोड की जाएंगी। और हम नहीं जानते कि कितनी मेमोरी पर्याप्त है। – James

+0

एक बार जब आप उन्हें सूचीबद्ध कर लेंगे, तो परिणाम के साथ आप क्या करने जा रहे हैं? – OscarRyz

उत्तर

5

मुझे पता है कि आपने "डिफ़ॉल्ट 64 एम ढेर सीमा के साथ" कहा है, लेकिन आइए तथ्यों को देखें - आप जावा द्वारा उपलब्ध कराई गई तंत्र का उपयोग करके स्मृति में बड़ी संख्या में आइटम (संभावित रूप से) रखना चाहते हैं। इसलिए, जब तक कि कोई गंभीर कारण नहीं है कि आप नहीं कर सकते, तो मैं कहूंगा कि ढेर बढ़ाना रास्ता है। टिप्पणी करने के लिए http://www.coderanch.com/t/381939/Java-General/java/iterate-over-files-directory

संपादित, जवाब में:

यहाँ एक JavaRanch पर एक ही चर्चा के लिए लिंक है, क्योंकि यह केवल है कारण मैं ने कहा कि वह स्मृति में मदों की एक बड़ी संख्या में धारण करने के लिए चाहता है तंत्र जावा मूल इंटरफ़ेस या प्लेटफ़ॉर्म-विशिष्ट तंत्र का उपयोग किए बिना निर्देशिका सूचीबद्ध करने के लिए प्रदान करता है (और ओपी ने कहा कि वह "शुद्ध जावा" चाहता था)।

+1

के समान कॉल करें कि जेम्स एक सरणी रिटर्न कर रहा है। सवाल यह है कि क्या आप किसी भी तरह से पूर्ण सरणी आवंटित किए बिना, किसी भी तरह निर्देशिका में नामों के लिए एक पुनरावर्तक के बराबर प्राप्त कर सकते हैं। यह एक उचित सवाल है; मुझे अपने सिर के ऊपर से जवाब नहीं पता है। –

+2

आप कोर जावा एपीआई के साथ नहीं कर सकते हैं। – danben

+0

हां, मैं जो चाहता हूं वह बिल्कुल एक फ़ाइलइटर – James

1

एक डीआईआर में 300 000 फाइलें रखना एक अच्छा विचार नहीं है - AFAIK फाइल सिस्टम एक नोड में कई उप-नोड्स रखने में अच्छा नहीं है। दिलचस्प सवाल, यद्यपि।

संपादित करें: अनुसरण करने में सहायता नहीं है, टिप्पणियां देखें।

मुझे लगता है कि आप एक फाइलफिल्टर का उपयोग कर सकते हैं, सभी फाइलों को अस्वीकार कर सकते हैं, और उन्हें फ़िल्टर में संसाधित कर सकते हैं।

 new File("c:/").listFiles(new FileFilter() { 
      @Override public boolean accept(File pathname) { 
       processFile(); 
       return false; 
      } 
     }); 
+0

एक्सएफएस एक निर्देशिका में बड़ी संख्या में फाइलों का समर्थन करता है। इसके अलावा, यह जवाब विषय से काफी दूर है। – danben

+1

बस java.io.File के लिए स्रोत की जांच की। यह फ़िल्टरिंग से पहले सूची को कॉल करेगा, इसलिए मूल समस्या बनी रहती है। – Gennadiy

+0

हां, मेरी इच्छा है कि लोग कम से कम उन उत्तरों को सत्यापित करें जो संशोधित करने से पहले "सही दिखें"। पोस्टर के लिए कोई अपराध नहीं है। – danben

2

आप यहां भाग्य से बाहर हैं। कम से कम 300k तारों को बनाने की आवश्यकता होगी। औसत लंबाई 8-10 चार और प्रति बाइट 2 बाइट जो न्यूनतम में 6 एमबी है। ऑब्जेक्ट पॉइंटर ओवरहेड प्रति स्ट्रिंग (8 बाइट्स) जोड़ें और आप अपनी मेमोरी सीमा में भाग लें।

यदि आपके पास पूरी तरह से एक ही डीआईआर में कई फाइलें होनी चाहिए, जो मैं आपकी फाइल सिस्टम में समस्याएं नहीं रखूंगा, तो आपकी सबसे अच्छी शर्त Runtime.exec के माध्यम से मूल प्रक्रिया (जेएनआई नहीं) चलाने के लिए है। ध्यान रखें कि आप स्वयं को ओएस (एलएस बनाम डीआईआर) से जोड़ देंगे। आप फ़ाइलों की एक सूची को एक बड़ी स्ट्रिंग के रूप में प्राप्त करने में सक्षम होंगे और जो भी आप चाहते हैं उसे पोस्ट करने के लिए जिम्मेदार होंगे।

उम्मीद है कि इससे मदद मिलती है।

3

आपके लिए एकमात्र संभावित समाधान जावा 7 है और फिर आप एक इटरेटर का उपयोग कर सकते हैं।

final Path p = FileSystems.getDefault().getPath("Yourpath"); 
Files.walk(p).forEach(filePath -> { 
     if (Files.isRegularFile(filePath)) { 
      //Do something with filePath 
     } 
}); 
+2

http://stackoverflow.com/questions/3139073/how-to-list-a-2-million-files-directory-in-java-without-having-a-out-of-memory-e/14241968# में 14241968 मैंने जावा 7 –

+0

['Path.iterator()'] (https://docs.oracle.com/javase/7/docs/api/java/nio/file) के साथ यह कैसे किया जाए, इसका एक सरल उदाहरण पोस्ट किया है। /Path.html#iterator()) पथ के नाम तत्वों पर पुनरावृत्त करता है, निर्देशिका में फ़ाइलों पर नहीं। – predi

0

यदि आप जावा 7 या ऊपर में अपना कोड लिख सकते हैं, तो निम्नलिखित एक अच्छा विकल्प है।

Files.newDirectoryStream (पथ dir)

Here एपीआई के लिए जावा दस्तावेज़ है।

उम्मीद है कि इससे मदद मिलती है।

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