2012-04-22 17 views
14

हर जावा कार्यान्वयन मैं एक फ़ाइल से पढ़ने के देख में, मैं लगभग हमेशा लाइन द्वारा लाइन को पढ़ने के लिए प्रयोग किया जाता है एक फ़ाइल पाठक देखते हैं। मेरा विचार यह होगा कि यह बहुत अक्षम होगा क्योंकि इसे प्रति पंक्ति एक सिस्टम कॉल की आवश्यकता होती है।जावा - एक फ़ाइल से पढ़ना। इनपुट धारा बनाम पाठक

क्या मैं बजाय कर रहा था एक इनपुट स्ट्रीम का उपयोग और सीधे बाइट्स हड़पने के लिए है। मेरे प्रयोगों में, यह काफी तेज़ है। मेरा परीक्षण एक 1 एमबी फाइल थी।

Text length: 1054631, Total time: 9 
Text length: 1034099, Total time: 22 

तो, क्यों लोग धाराओं के बजाय पाठकों का उपयोग करते हैं:

//Stream method 
    try { 
     Long startTime = new Date().getTime(); 

     InputStream is = new FileInputStream("test"); 
     byte[] b = new byte[is.available()]; 
     is.read(b); 
     String text = new String(b); 
     //System.out.println(text); 

     Long endTime = new Date().getTime(); 
     System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime)); 

    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

    //Reader method 
    try { 
     Long startTime = new Date().getTime(); 

     BufferedReader br = new BufferedReader(new FileReader("test")); 
     String line = null; 
     StringBuilder sb = new StringBuilder(); 
     while ((line = br.readLine()) != null) { 
      sb.append(line); 
      sb.append("\n"); 
     } 
     String text = sb.toString(); 

     Long endTime = new Date().getTime(); 
     System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime)); 

    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

इस का एक परिणाम देता है?

यदि मेरे पास कोई तरीका है जो एक टेक्स्ट फ़ाइल लेता है और एक स्ट्रिंग देता है जिसमें सभी पाठ होते हैं, तो क्या यह स्ट्रीम का उपयोग करके इसे बेहतर करना बेहतर है?

+0

आपका कोड सही नहीं है। यह गारंटी नहीं है कि यह पूरी फाइल को पढ़ेगा, पढ़ने और उपलब्ध विधियों के दस्तावेज देखें। – Milo

+1

क्या आपने [java.nio.File] पर अपने हाथों की कोशिश की थी (http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html) पैकेज की फ़ाइलें .readAllLines (.. ।) तरीका। –

+0

+1 कुछ नया सीखने के लिए +1 – panny

उत्तर

10

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

+0

यह बहुत दिलचस्प है। स्थानीय फ़ाइल सिस्टम पर मौजूद एक सादे पाठ फ़ाइल से पढ़ने पर खतरनाक उपलब्ध है? – Jeremy

+0

@ जेरेमी ['उपलब्ध'] का उपयोग करने के लिए कभी भी सही नहीं है (http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available()) के लिए एक बफर आवंटित करने के लिए एक धारा की पूरी तरह से। – Jeffrey

+0

@ जेफरी यदि आपके पास है, तो मुझे आपके पास कोई भी संसाधन देखना अच्छा लगेगा। इससे पहले कि मैं किसी भी मुद्दे पर चलने के बिना काफी खुशी से उपयोग कर रहा था। मैं आपको विश्वास करता हूं, लेकिन मुझे आश्चर्य है कि वास्तव में ऐसी स्थिति है जहां उपलब्ध है। – Jeremy

3

FileReader आमतौर पर BufferedReader के संयोजन के साथ प्रयोग किया जाता है क्योंकि अक्सर फ़ाइल द्वारा फ़ाइल लाइन को पढ़ने के लिए समझदारी होती है, विशेष रूप से यदि फ़ाइल में एक अच्छी तरह से परिभाषित रिकॉर्ड संरचना है जहां प्रत्येक रिकॉर्ड एक रेखा से मेल खाता है। चरित्र फ़ाइलों को पढ़ने के लिए

सुविधा वर्ग:

इसके अलावा, FileReader रूप javadocs में कहा गया है, वर्ण एन्कोडिंग और रूपांतरण से निपटने के लिए काम से कुछ को आसान बनाने में कर सकते हैं। इस वर्ग के निर्माताओं को लगता है कि डिफ़ॉल्ट वर्ण एन्कोडिंग और डिफ़ॉल्ट बाइट-बफर आकार उपयुक्त हैं ... FileReader पात्रों की धाराओं पढ़ने के लिए है।

3

BufferedReader बफर आकार बढ़ाने की कोशिश करें। उदाहरण के लिए:

BufferedReader br = new BufferedReader(new FileReader("test"),2000000); 

आप सही बफर आकार चुनते हैं, तो आप तेजी से किया जाएगा।

फिर Reader के साथ अपने नमूने में आप StringBuilder भरने समय बिताते हैं। यदि आपको लाइनों को संसाधित करने की आवश्यकता है तो आपको लाइन लाइन फ़ाइल को पढ़ना होगा। लेकिन यदि आप केवल एक स्ट्रिंग में एक पाठ पढ़ने की जरूरत है तो public int read(char[] cbuf) के साथ पाठ का बड़ा हिस्सा पढ़ सकते हैं और एक StringWriter एक उचित आकार के साथ प्रारंभ में हिस्सा लिखें।

InputStream या Reader का उपयोग करने के लिए चुनें प्रदर्शन पर निर्भर नहीं करता है। आम तौर पर आप Reader का उपयोग करके ऐसी पाठ डेटा को पढ़ने, क्योंकि रीडर के साथ आप और अधिक आसानी से चारसेट संभाल कर सकते हैं।

एक और मुद्दा, अपने कोड यहाँ

byte[] b = new byte[is.available()]; 
is.read(b); 
String text = new String(b); 

यह सही नहीं है। documentation

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

इसलिए ध्यान दें, आपको इसे ठीक करने की आवश्यकता है।

+0

मैन्युअल रूप से बफर आकार की आपूर्ति करना मेरे लिए नकारात्मक प्रभाव को प्रभावित करता है। – Jeremy

+0

आपकी फाइल कितनी बड़ी है? आप अपने जेवीएम को कितना ढेर समर्पित करते हैं? – dash1e

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