To use XMLStreamReader I am ini开发者_如何学JAVAtializing it like -
XMLInputFactory f = XMLInputFactory.newInstance();
XMLStreamReader reader = f.createXMLStreamReader(new FileReader(
"somefile.xml"));
Iterating over it like -
if (reader.hasNext()) {
reader.next();
// do something with xml data
}
Finally closing it like -
reader.close();
This looks to be a normal flow but I am seeing some strange behavior. Even after closing reader, OS doesn't allow me delete/move the xml file unless I exit from java program. When run on Win2k8-server, I get error message saying java.exe is using this xml file.
So I have couple of questions -
- Do I need to explicitly close each FileReader's close?
- How can I find out which java code path is keeping this file handle open.
Looking @ the documentation of XMLStreamReader's close(), I get following - "Frees any resources associated with this Reader. This method does not close the underlying input source."
What is the meaning of "underlying input source"? Why is that not closed by reader's close()?
The underlying input source mentioned in the doc is exactly what you should close. Put the FileReader into a local variable to be able to close it:
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
What is the meaning of "underlying input source"? Why is that not closed by reader's close()?
You created XMLReader by XMLInputFactory.createXMLStreamReader with argument InputStream or so. This is an "underlying input source". :) Because it opened outside of XMLReader, thus XMLReader will not close it. But, if you need, can use this wrapper class for XMLReader. Just works.
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);
}
}
}
精彩评论