2011-05-07 77 views
6

要使用的XMLStreamReader我初始化它喜歡 -XMLStreamReader的不關閉打開XML文件

XMLInputFactory f = XMLInputFactory.newInstance(); 
XMLStreamReader reader = f.createXMLStreamReader(new FileReader(
     "somefile.xml")); 

遍歷它喜歡 -

if (reader.hasNext()) { 
    reader.next(); 
    // do something with xml data 
} 

最後關閉它喜歡 -

reader.close(); 

這看起來是一個正常的流程,但我看到一些奇怪的行爲。即使在關閉閱讀器之後,操作系統也不允許刪除/移動xml文件,除非我退出Java程序。在Win2k8服務器上運行時,出現錯誤消息,說java.exe正在使用此xml文件。

所以,我有幾個問題 -

  1. 我需要明確關閉每個的FileReader收盤?
  2. 如何找出哪個java代碼路徑使這個文件句柄保持打開狀態。

尋找@ XMLStreamReader的close()的文檔,我得到以下內容 - 「釋放與此Reader相關的任何資源。此方法不會關閉底層輸入源。

「底層輸入源」是什麼意思? 爲什麼讀者的close()沒有關閉?

回答

9

文檔中提到的底層輸入源正是您應該關閉的內容。把的FileReader到一個局部變量,以便能夠將其關閉:

XMLInputFactory f = XMLInputFactory.newInstance(); 
FileReader fr = new FileReader("somefile.xml"); 
XMLStreamReader reader = f.createXMLStreamReader(fr); 

// process xml 

reader.close(); 
fr.close(); 

//suggest using apache commons IOUtils.closeQuietly(fr); this way you 
// don't have to deal with exceptions if you don't want 
+0

[關閉()](http://download.oracle.com/javase/6/docs/api/javax/xml/stream/XMLStreamReader.html#close())方法的明確的API說它不關閉底層的_Reader_對象。也許在答案中引用API中的句子。 – Progman 2011-05-07 15:02:01

+0

什麼對我的第二個問題 - 我如何找出哪個Java代碼路徑保持這個文件句柄打開? – siddharth178 2011-05-09 12:00:35

1

什麼是「基本輸入源」的含義是什麼?爲什麼讀者的close()沒有關閉?

您通過XMLInputFactory.createXMLStreamReader創建了帶有參數InputStream左右的XMLReader。這是一個「潛在輸入源」。 :)因爲它在XMLReader之外打開,所以XMLReader不會關閉它。但是,如果您需要,可以使用此包裝器類作爲XMLReader。只是工作。

import java.io.IOException; 
import java.io.InputStream; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import javax.xml.stream.XMLInputFactory; 
import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.XMLStreamReader; 
import javax.xml.stream.util.StreamReaderDelegate; 

public class XMLFileReader extends StreamReaderDelegate implements AutoCloseable { 
    private final static XMLInputFactory factory = XMLInputFactory.newFactory(); 
    private final Path file; 
    private final InputStream stream; 
    private final XMLStreamReader reader; 

    public XMLFileReader(Path file) throws IOException, XMLStreamException { 
     super(); 
     this.file = file; 
     stream = Files.newInputStream(this.file); 
     reader = factory.createXMLStreamReader(stream); 
     setParent(reader); 
    } 

    @Override 
    public void close() throws XMLStreamException { 
     try { 
      super.close(); 
      stream.close(); 
     } catch (IOException e) { 
      throw new XMLStreamException(file+" : "+e.getMessage(),e); 
     } 
    } 
}