2012-11-02 12 views
5

मेरे प्रोग्राम में मेरे पास लूप है जो फ़ाइलों का एक समूह स्कैन करता है और उनकी सामग्री को पढ़ता है। समस्या लगभग 1500 फ़ाइलों की यात्रा से अधिक हुआ है और (या समझ में आ (मेरे द्वारा)) पुनः प्रस्तुत किया जाना नहीं कर पा रहेबहुत अधिक खुली फ़ाइल त्रुटि, java.io.FileNotFoundException

समस्या:

java.io.FileNotFoundException: /path/to/file//myFile (Too many open files) 

अपवाद इस विधि को अंक:

private static String readFileAsRawString(File f) throws IOException { 

    FileInputStream stream = new FileInputStream(f); // <------------Stacktrace 
    try{ 
     FileChannel fc = stream.getChannel(); 
     MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); 

     return Charset.defaultCharset().decode(bb).toString(); 
    } finally { 
     stream.close(); 
    } 
} 

मैंने इस विधि को क्यूए में 20,000 से अधिक फाइलों में भाग लिया और ऐसा कोई समस्या नहीं है।

क्या आप ऊपर दिए गए कोड के साथ कुछ भी गलत देखते हैं जो इस मुद्दे का कारण बनता है?

+0

क्या आपने दोनों वातावरणों में एक ही ओएस का उपयोग किया था (क्यूए और जो असफल रहा?) – SJuan76

+0

नहीं। उत्पादन प्रणाली लिनक्स है, मेरे परीक्षण मैक – JAM

+0

फ़ाइल को बंद करने से पहले डेटा लौट रहे हैं। शायद समस्या का कारण बन रहा है। अंत में ब्लॉक के बाद वापसी रखने का प्रयास करें। – Romaan

उत्तर

3

मैपिंग पर संदेह है। MappedByteBuffer अपने FileChannel से अधिक हो सकता है, और जब तक यह कचरा एकत्र नहीं किया जाता है तब तक वैध है। आपके पास जीसी चलाने के लिए पर्याप्त कचरा नहीं हो सकता है, लेकिन शायद एक विशेष मंच फ़ाइल हैंडल पर बिना संदर्भित बफर द्वारा बनाए रखा जाता है।


जब तक स्पष्ट कचरा संग्रहण अक्षम है (-XX:-DisableExplicitGC), आप, अपवाद को पकड़ने System.gc() आह्वान करने और फिर से कोशिश कर रहा द्वारा इस बात के लिए परीक्षण करने के लिए सक्षम होना चाहिए। अगर यह दूसरी कोशिश पर काम करता है, तो यह आपकी समस्या है। हालांकि, एक स्थायी फिक्स के रूप में System.gc() पर कॉल करना एक बुरा विचार है। समाधान जो समग्र रूप से सर्वश्रेष्ठ प्रदर्शन करेगा, लक्ष्य प्लेटफॉर्म पर कुछ प्रोफाइलिंग करेगा।

+0

मेरी मशीन (मैक) पर समस्या को पुन: पेश करने में मेरी असमर्थता क्या है, मैं निश्चित रूप से यह सत्यापित करूंगा कि यह सोमवार को प्रोड (लिनक्स) में कैसे व्यवहार करता है। – JAM

+0

+1 जीसी तक मैपडबेट बफर को अनैप करने का कोई तरीका नहीं है। – irreputable

-1

मुझे लगता है कि आप तेजी से बहुत सारी फाइलें खोलते हैं, इसका परीक्षण करने के लिए प्रतीक्षा() जोड़ने का प्रयास करें। फिर एक स्थिर काउंटर जोड़ें जो खुलने वाली फ़ाइलों के ट्रैक रखता है और यदि कई फाइलें पहले से खुली हैं, तो प्रतीक्षा प्रणाली जोड़ें ...

+1

क्यों? गति के साथ क्या करना है, और प्रतीक्षा क्यों मदद करेगा? अस्पष्ट अनुमान कार्य नहीं है। -1। – EJP

2

इस छोटे कार्य के लिए मैप्डबेट बफर का उपयोग न करें। कोई अच्छी तरह परिभाषित समय नहीं है जिस पर उन्हें रिहा किया जाता है। बस फ़ाइल खोलें, इसे पढ़ें, इसे बंद करें।

+0

भी सच है। – JAM

+0

अपाचे की 'FileUtils.readFileToString (f); 'कम कोड और क्लीनर समाधान की तरह लगता है। सोमवार को परीक्षण करेंगे। – JAM

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