содержимое файла XML, созданного приложением Java, исчезает, если компьютер выключен - PullRequest
2 голосов
/ 07 июля 2011

Я разработал настольное приложение, которое имеет класс, который читает файл XML (используя DOM), затем выполняет некоторые операции с данными и сохраняет данные обратно в XML (заменяя предыдущий файл).Этот класс создается, и метод вызывается каждые 30 секунд.Проблема у меня заключается в том, что если компьютер, на котором запущено приложение, выключается (внезапно с кнопкой питания, не правильно).затем, когда компьютер запускается снова, файл XML пуст.Пустой файл остается.Это происходит не каждый раз, когда компьютер выключается, но очень часто.Если компьютер правильно выключен, это никогда не происходит.Это код:

private org.w3c.dom.Document dom;
private javax.xml.parsers.DocumentBuilder db;

public PlayerConfigHandler() {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    try {
        db = dbf.newDocumentBuilder();
        dom = db.newDocument();
    } catch (Exception e) {  }
}

public void updateConfig(List<File> playlists) {
    String playerPath = Preferences.getInstance().readStringProperty("PlayerDirectory");
    File configuration = new File(playerPath + "\\playerconfiguration.sdpp"); // replace with configuration path
    if(!configuration.exists()) {
        Logger.getLogger(PlayerConfigHandler.class).info("File " + configuration 
                + " does not exist! Unable to update it.");
        return;
    }
    dom = db.newDocument();
    InputStream is = null;
    Reader reader = null;
    try {
        is = new FileInputStream(configuration);
        reader = new InputStreamReader(is);
        InputSource source = new InputSource(reader);
        dom = db.parse(source);
    } catch (SAXException ex) {
        Logger.getLogger(PlayerConfigHandler.class).error("updateConfig(). SAXException reading XML file: " + ex);
        return;
    } catch (IOException ex) {
        Logger.getLogger(PlayerConfigHandler.class).error("updateConfig(). IOException reading XML file: " + ex);
        return;
    } catch(Exception ex) {
        Logger.getLogger(PlayerConfigHandler.class).error("updateConfig(). Exception reading XML file: " + ex);
        return;
    } finally {
        try {
            reader.close();
            is.close();
        } catch (Exception e) { 
            Logger.getLogger(PlayerConfigHandler.class).error("Exception closing FileInputStream/Reader after reading XML file: " + e);
        }
    }
    Element element = dom.getDocumentElement();

    //perform some operations to the data read...

    FileOutputStream outputStream = null;
    try {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        transformerFactory.setAttribute("indent-number", 4);
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty("encoding","ISO-8859-1");
        Source source = new DOMSource(dom);
        outputStream = new FileOutputStream(configuration);
        Result result = new StreamResult(new OutputStreamWriter(outputStream));
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.transform(source, result);
    } catch (TransformerConfigurationException tce) {
        Logger.getLogger(PlayerConfigHandler.class).error("Exception saving XML file: " + tce);
    } catch (TransformerException te) {
        Logger.getLogger(PlayerConfigHandler.class).error("Exception saving XML file: " + te);
    } catch (FileNotFoundException fe) {
        Logger.getLogger(PlayerConfigHandler.class).error("Exception saving XML file: " + fe);
    } catch(Exception e) {
        Logger.getLogger(PlayerConfigHandler.class).error("Exception saving XML file: " + e);
    }
    finally {
        try {
            outputStream.close();
        } catch (Exception e) { 
            Logger.getLogger(PlayerConfigHandler.class).error("Exception closing FileOutputStream after writing XML file: " + e);
        }
    }
    dom = db.newDocument();
}

Есть идеи, почему это происходит?Что-то не так в коде?Есть ли способ предотвратить это?Спасибо, Дамиан

Ответы [ 3 ]

3 голосов
/ 07 июля 2011

new FileOutputStream усекает файл, и компьютер выключается перед записью и закрытием любых новых данных.Этот простой пример демонстрирует проблему.Если вы запустите это один раз, отредактируйте foo.txt и запустите его снова, содержимое будет усечено.

import java.io.*;

public class FileCreate {
    public static void main(String[] args) throws Exception {
        File f = new File("C:\\temp\\foo.txt");
        FileOutputStream outputStream = new FileOutputStream(f);
        outputStream.close();
    }
}

Один из способов решения этой проблемы - записать новую конфигурацию в другой файл и затем выполнить командуудалить "и" переименовать ".

2 голосов
/ 07 июля 2011

Когда программа открывает файл для записи, она очищает содержимое файла.

Если компьютер выключается после того, как это происходит, но перед тем, как закрыть поток, очень вероятно, что любые записанные вами данные не будут сброшены в файл до завершения.

1 голос
/ 07 июля 2011

Чтобы предотвратить подобные вещи, вы можете открыть свой файл и прочитать его, выполнить некоторые операции, сохранить его в другом файле, и они заменят первый файл вторым (например, rename).

Таким образом, когда вы выключите компьютер, у вас будет старый файл.

Но это не суперзащита: может случиться так, что компьютер выключится в тот момент, когда он заменяет файл, оставляя васс поврежденным файлом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...