【问题标题】:xstream - correct way to save XML in UTF-8xstream - 以 UTF-8 保存 XML 的正确方法
【发布时间】:2023-04-01 19:22:01
【问题描述】:

以前,为了通过 xstream 以 UTF-8 编码读取 XML,我使用 DomDriver 如下:

XStream xStream = new XStream(new DomDriver("UTF-8"));

但是,后来我意识到这非常慢。我使用以下方式:

Optimize loading speed of xstream

这至少可以正常工作。

但是,后来,我意识到不能将相同的技术应用于编写 XML。我会得到所有的???字符。

这是在 write

期间使用 DomDriver 的最后一个可行代码
public static boolean toXML(Object object, File file) {
    XStream xStream = new XStream(new DomDriver("UTF-8"));
    OutputStream outputStream = null;

    try {
        outputStream = new FileOutputStream(file);
        xStream.toXML(object, outputStream);
    }
    catch (Exception exp) {
        log.error(null, exp);
        return false;
    }
    finally {
        if (false == close(outputStream)) {
            return false;
        }
        outputStream = null;
    }

    return true;
}

上面的代码工作正常。为了匹配不使用DomDriver的read方法,我将代码改为

public static boolean toXML(Object object, File file) {
    XStream xStream = new XStream();
    OutputStream outputStream = null;
    Writer writer = null;

    try {
        outputStream = new FileOutputStream(file);
        writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
        xStream.toXML(object, outputStream);
    }
    catch (Exception exp) {
        log.error(null, exp);
        return false;
    }
    finally {
        if (false == close(writer)) {
            return false;
        }
        if (false == close(outputStream)) {
            return false;
        }
        writer = null;
        outputStream = null;
    }

    return true;
}

这一次,我所有的汉字都变成了???

我可以知道我做错了什么吗?

【问题讨论】:

  • 嗨 - 您在上述方法中作为“对象”传递了什么?

标签: java xml xstream


【解决方案1】:

看这段代码:

outputStream = new FileOutputStream(file);
writer = new OutputStreamWriter(outputStream, Charset.forName("UTF-8"));
xStream.toXML(object, outputStream);

您正在创建一个将使用 UTF-8 的编写器 - 但随后完全忽略了它!

试试这个:

xStream.toXML(object, writer);

另外,作为风格问题,我建议您考虑以下几点:

  • 不要将结果与布尔常量进行比较;只需使用 if (foo)if (!foo) 代替
  • 捕捉Exception非常很少是个好主意;而是捕获特定异常
  • 返回一个布尔值来指示成功或失败不是 Java 的惯用语;通常,如果某些事情失败了,最好抛出一个异常
  • 如果第一个close 失败,您将在第二个close 调用之前退出该方法,这可能不是您想要的。 (其实关闭OutputStreamWriter`无论如何都会关闭流,但要考虑事情的原理。)
  • 在方法结束时将局部变量设置为 null 是不必要的,并且会使您的代码混乱

【讨论】:

  • @Jon 天哪!你有一双敏锐的眼睛!
  • 我认为还有额外的错误,我不应该在 finally 块中返回。相反,我应该使用 boolean status = close(writer); status = status & close(outputStream);... 并在方法的最后返回状态。
  • @Yan:从 finally 块返回是可以的,只要你小心点。特别是,从 finally 块的 end 返回是可以的。您只是不想因为中途返回而错过一些清理代码。
  • @Yan:更重要的是 - 在toXML 调用中使用writer 的更改对您有用吗? :)
  • 是的。 toXML 有效。关于你对finally的评论,你以前见过吗? *.com/questions/48088/…