XMLStreamReader не закрывает открытый XML-файл - PullRequest
7 голосов
/ 07 мая 2011

Для использования 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();

Это выглядит как нормальный поток, но я вижу странное поведение. Даже после закрытия программы чтения ОС не позволяет мне удалять / перемещать XML-файл, пока я не выйду из Java-программы. При запуске на Win2k8-сервере появляется сообщение об ошибке, в котором говорится, что java.exe использует этот xml-файл.

Итак, у меня есть пара вопросов -

  1. Нужно ли явно закрывать закрытие каждого FileReader'а?
  2. Как узнать, какой путь к коду Java поддерживает этот дескриптор файла.

Просматривая @ документацию о XMLStreamReader's close (), я получаю следующее: «Освобождает любые ресурсы, связанные с этим Reader. Этот метод не закрывает основной источник ввода». *

Что означает «базовый источник ввода»? Почему это не закрывается читателем close ()?

Ответы [ 2 ]

10 голосов
/ 07 мая 2011

Основной источник входного сигнала, упомянутый в документе, является именно тем, что вы должны закрыть.Поместите 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
1 голос
/ 14 февраля 2018

Что означает «базовый источник ввода»? Почему это не закрывается читателем 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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...