2012-03-06 14 views
15

बंद DocumentBuilder.parse निम्न के समान कोड के लिए करता है। क्या दस्तावेज़बिल्डर मेरे लिए इनपुटस्ट्रीम बंद करता है?InputStream

उत्तर

7

इनपुट स्ट्रीम बंद है या नहीं, यह देखने के लिए निम्न परीक्षण कोड का उपयोग करें, और आप देख सकते हैं कि कोड की कौन सी रेखा स्ट्रीम बंद कर देती है।

public class DocumentBuilderTest { 

public static void main(String[] args) { 
    try { 
    InputStream is = new MyInputStream("project.xml"); 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder documentBuilder = dbf.newDocumentBuilder(); 
    documentBuilder.parse(is); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    } 
} 

static class MyInputStream extends FileInputStream { 
    public MyInputStream(String filename) throws FileNotFoundException { 
    super(filename); 
    } 

    @Override 
    public void close() throws IOException { 
    // here we log when the stream is close. 
    System.out.println("file input stream closed."); 
    Exception e = new Exception(); 
    e.printStackTrace(); 
    super.close(); 
    } 

} 
} 

क्या दस्तावेज़बिल्डर को पास की गई इनपुट स्ट्रीम बंद है या नहीं, DOMParser कार्यान्वयन पर निर्भर करता है। मेरी वातावरण में, फ़ाइल इनपुट स्ट्रीम बंद कर दिया है, नीचे दिए गए स्टैक ट्रेस देखें:

at DocumentBuilderTest$MyInputStream.close(DocumentBuilderTest.java:37) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager$RewindableInputStream.close(XMLEntityManager.java:3047) 
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.close(UTF8Reader.java:661) 
at com.sun.xml.internal.stream.Entity$ScannedEntity.close(Entity.java:441) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.endEntity(XMLEntityManager.java:1406) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1763) 
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipSpaces(XMLEntityScanner.java:1543) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$TrailingMiscDriver.next(XMLDocumentScannerImpl.java:1400) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) 
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119) 
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:235) 
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284) 
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124) 
at DocumentBuilderTest.main(DocumentBuilderTest.java:22) 

तो आप मैन्युअल रूप से इस विशिष्ट उदाहरण में धारा को बंद नहीं कर सका। हालांकि, जब आप सुनिश्चित हैं कि स्ट्रीम का उपयोग नहीं किया जाएगा, तो इनपुट स्ट्रीम को बंद करना हमेशा अच्छा विचार है। आपके मामले में, दस्तावेज़ को पार्स करने के बाद, इनपुट स्ट्रीम की आवश्यकता नहीं होती है, इसलिए स्ट्रीम सुरक्षित रूप से बंद हो सकती है, और मेरा सुझाव है कि आप ऐसा करते हैं।

2

प्रलेखन स्ट्रीम को बंद करने का कोई उल्लेख नहीं करता है, और मैं उम्मीद करता हूं कि यह आपके लिए स्ट्रीम बंद न करे।

निश्चित होने के लिए, आप स्रोत कोड पढ़ सकते हैं, या जांच सकते हैं कि यह पार्स() को कॉल करने के बाद एक साधारण उदाहरण मामले में खुला है या नहीं।

लेकिन संक्षिप्त उत्तर: हाँ, आपको इसे बाद में मैन्युअल रूप से बंद करने की आवश्यकता है।

+0

को बंद करने के लिए विधि कार्यान्वयन मैं एक साधारण उदाहरण बनाउंगा। –

+0

कोई समस्या नहीं है। साथ ही, मुझे लगता है कि स्पष्ट रूप से ऐसा कहने के बिना, विधि इसे बंद नहीं करेगी। मैं ऑब्जेक्ट्स पर अभिनय करने की विधियों की अपेक्षा करता हूं, मैं उन्हें जितनी छोटी हो सके वस्तुओं पर कार्य करने के लिए पास करता हूं। कॉलिंग। क्लोज() को मेरे लिए ज़िम्मेदारी का उल्लंघन माना जाएगा (पार्स विधि में कोई व्यवसाय कॉलिंग नहीं है। क्लोज़())। – Corbin

+1

मेरे आश्चर्य के लिए, DocumentBuilder.parse मेरे उदाहरण में स्ट्रीम बंद करें। –

3

सामान्य अनुबंध यह है कि संसाधन प्राप्त करने वाले कोड को इसे जारी करना होगा। यह अच्छा अभ्यास है क्योंकि इसका मतलब है कि अगर किसी भी हस्तक्षेप कोड द्वारा अपवाद फेंक दिया जाता है, तो आप संसाधन को रिसाव नहीं करते हैं। पूर्व जावा 7 के लिए

try (InputStream in = new FileInputStream("foo")) { 
    // process data 
} 

:

एक try-with-resources ब्लॉक का उपयोग करें

InputStream in = new FileInputStream("foo"); 
try { 
    // process data 
} finally { 
    in.close(); 
} 
0

अपनी जरूरत अपनी स्ट्रीम डोम पार्स करने (क्रम में जारी रखने के लिए सक्षम होने के लिए के बाद से बंद नहीं किया है करने के लिए था तो इसे पढ़ने के लिए, उदाहरण के लिए), यह धागा देखें: Java create InputStream from ZipInputStream entry

3

मैंने फ़िल्टरइनपुटस्ट्रीम का विस्तार करने के लिए क्या किया है, और नज़दीकी() मी ओवरराइड किया है इनपुटस्ट्रीम

public class HackInputStream 
    extends FilterInputStream { 

    public HackInputStream(InputStream in) { 
     super(in); 
    } 

    @Override 
    public void close() { 
     // this does not close stream. 
     // use hackedClose() instead. 
    } 

    public void hackedClose() 
      throws IOException { 
     super.close(); 
    } 


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