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);
        }
    }
}
