【问题标题】:Marshalling a JAXB Object Overwrites Previously Marshalled Files编组 JAXB 对象会覆盖以前编组的文件
【发布时间】:2017-05-29 17:36:53
【问题描述】:

所以这是一个我还没有解决的有趣问题...我将从代码开始,然后是一些背景知识。

public void encodeElements(String path) throws Exception {
    LOGGER.warning("Marshalling config to " + path);
    JAXBContext ctx = JAXBContext.newInstance(RootElement.class);

    Marshaller marshaller = ctx.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    RootElement ele = new RootElement();
    ele.setDummyField("abc");

    QName qName = new QName("http://localhost/xml-schemas/mySchema", "rootelement");
    JAXBElement<RootElement> root = new JAXBElement<RootElement>(qName, RootElement.class, ele);

    marshaller.marshal(root, new FileOutputStream(path));
}

此应用的 GUI 上有一个“另存为”选项。每次调用此函数时,它都会覆盖使用“另存为”功能保存的先前文件。例如:

  • 打开应用
  • 另存为 - “1.xml” - 这里一切正常
  • 另存为 - “2.xml”

    调用 JAXBContext.newInstance() 会用 2.xml 的内容覆盖 1.xml,并且还会创建一个有效的 2.xml。区分这两个文件表明它们实际上是相同的。重复此过程始终会覆盖上次保存的文件。 (IE 另存为 3.xml 将覆盖 2.xml 并创建一个相同的 3.xml,依此类推)。

    在调试器中逐步执行此操作向我显示JAXBContext ctx = JAXBContext.newInstance(RootElement.class); 是覆盖前一个文件的行。

    我不知道从哪里调用先前保存的文件的信息。我已经开始挖掘源代码 (here),但没有任何帮助。任何帮助或见解表示赞赏。

    PS - 该链接是正确的来源。我们在使用 JAXB 2.2.11 的 Java 1.6 平台上。对平台的任何蔑视都可以不言而喻,因为我也有同感。

【问题讨论】:

  • 如需更好的帮助,请考虑创建并发布Minimal, Complete, and Verifiable Example Program。我们不想看到你的整个程序,而是你应该将你的代码压缩成仍然可以编译的最小部分,没有与你的问题无关的额外代码,但仍然可以证明你的问题。您可以通过简单地尝试隔离和暴露错误来自己解决问题。
  • 另外,请不要链接到代码。让您的问题尽可能容易回答符合您的最大利益。
  • 我的猜测是您的问题与您发布的代码无关,问题出在其他地方,但是没有有效的 MCVE,我无法测试或验证这一点。
  • 我看到你提供的链接是指向 Java 源代码的——我也陷入了这个陷阱——我认为这个错误不可能出现在我的代码中,我已经来回测试它,所以这个错误一定是 Java 的错——我后来发现自己错了 10,000 次:1。我猜你的几率和我的一样好。首先假设错误是你的,首先隔离错误(mcve 将帮助解决这个问题),直到你可以在这里发布一个有效的测试用例证明它是 Java 的错误,继续假设它是你的.
  • 感谢您的反馈。我将编辑我的帖子,使其符合这些准则。通过将源代码发布到 Java,我并不是在暗示这是 Java 的错。我只是一个孤独的开发者。我只是在发帖,以防我完全不了解它们是如何协同工作的。

标签: java xml jaxb


【解决方案1】:

原来问题出在这里: marshaller.marshal(root, new FileOutputStream(path));

写入完成后,传入的流不会关闭。所以,我们不得不自己关闭它:

FileOutputStream fos = new FileOutputStream(path);
marshaller.marshal(root, fos);
fos.close();

感谢观看的人。希望这对将来的某人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多