2011-05-07 80 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); 
     } 
    } 
}