如果计算机关闭,由 java 应用程序创建的 XML 文件的内容将消失

发布于 2024-11-19 04:41:10 字数 3678 浏览 1 评论 0原文

我开发了一个桌面应用程序,其中有一个类读取 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();
}

知道为什么会发生这种情况吗?代码有什么问题吗?有什么办法可以防止这种情况发生吗? 谢谢,达米安

I developed a desktop application, which has a class that reads a XML file (using DOM), then performs some operations to the data, and saves the data back to XML (replacing previous file). This class is instantiated and the method invoked every 30 seconds. The problem I have is that if the computer running the application is shutdown (suddenly with the power button, not properly). then, when pc starts again, the XML file is empty. A blank file remains. This doesn't happen every single time the computer is shut down, but very often though. If the computer is properly turned off, this never happens.
This is the code:

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

Any idea of why this happens? Is there anything wrong in the code? Is there any way to prevent this?
Thanks, Damian

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦中楼上月下 2024-11-26 04:41:11

当程序打开要写入的文件时,它会清除文件的内容。

如果计算机在发生这种情况之后关闭,但在关闭流之前关闭,则您写入的任何数据很可能在终止之前不会刷新到文件中。

When the program opens the file to write, it clears out the contents of the file.

If the computer shuts off after this occurs, but before you close the stream, it is very likely that any data you have written does not get flushed to the file before termination.

情深已缘浅 2024-11-26 04:41:11

为了防止这种情况发生,您可以打开文件并读取它,执行一些操作,将其保存在另一个文件中,然后用第二个文件替换第一个文件(如重命名)。

这样,当您关闭计算机时,您将拥有旧文件。

但这并不是超级安全:在替换文件时可能会关闭计算机,从而给您留下损坏的文件。

To prevent such thing, you could open your file and read it, perform some operations, save it in another file, and them replace the first file with the second (like a rename).

This way, when you turn the computer off, you'll have the old file.

But this is not super-secure: there might happen to turn the computer off in the moment it's replacing the file, leaving you with an corrupted file instead.

毁梦 2024-11-26 04:41:10

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

解决此问题的一种方法是将新配置写入不同的文件,然后执行“删除”和“重命名”。

The new FileOutputStream is truncating the file and the computer is turned off before any new data is written and closed. This simple example demonstrates the problem. If you run this once, edit foo.txt then run it again, the contents will be truncated.

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

One way to resolve this is to write the new configuration to a different file and then perform a "delete" and "rename".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文