XMLStreamReader не закрывает открытый xml-файл
для использования XMLStreamReader я инициализирую его как -
XMLInputFactory f = XMLInputFactory.newInstance();
XMLStreamReader reader = f.createXMLStreamReader(new FileReader(
"somefile.xml"));
итерация над ним, как -
if (reader.hasNext()) {
reader.next();
// do something with xml data
}
наконец-то это нравится -
reader.close();
это выглядит как нормальный поток, но я вижу какое-то странное поведение. Даже после закрытия reader ОС не позволяет мне удалять / перемещать xml-файл, если я не выхожу из java-программы. При запуске на Win2k8-сервере я получаю сообщение об ошибке java.exe использует этот xml-файл.
Итак, у меня есть пара вопросы -
- нужно ли явно закрывать закрытие каждого FileReader?
- как я могу узнать, какой путь кода java держит этот дескриптор файла открытым.
глядя @ документацию xmlstreamreader close (), я получаю следующее - "освобождает любые ресурсы, связанные с этим читателем. Этот метод не закрывает базовый источник ввода."
что означает "базовый источник ввода"? Почему это не закрыто читателя закрыть()?
2 ответов
базовый источник ввода, упомянутый в документе, - это именно то, что вы должны закрыть. Поместите 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
что означает "базовый источник ввода"? Почему это не закрыто reader's close ()?
Вы создали XMLReader с помощью XMLInputFactory.createXMLStreamReader с аргументом InputStream или около того. Это "базовый источник ввода". :) Поскольку он открылся за пределами 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);
}
}
}