【问题标题】:Skip BOM using BOMInputStream and retrieve byte[] without BOM使用 BOMInputStream 跳过 BOM 并在没有 BOM 的情况下检索 byte[]
【发布时间】:2020-10-07 13:11:01
【问题描述】:

我有一个带有 BOM(UTF-8 编码)的 xml 文件。该文件以byte[] 的形式出现。我需要跳过 BOM,然后将这些字节转换为字符串。

这就是我的代码现在的样子:

BOMInputStream bomInputStream = new BOMInputStream(new ByteArrayInputStream(requestDTO.getFile())); // getFile() returns byte[]

bomInputStream.skip(bomInputStream.hasBOM() ? bomInputStream.getBOM().length() : 0);

validationService.validate(new String(/*BYTE[] WITHOUT BOM*/)); // throws NullPointerException

我正在使用 BOMInputStream。我有几个问题。第一个是bomInputStream.hasBOM() 返回false。第二个,我不知道以后如何从bomInputStream 中检索byte[],因为bomInputStream.getBOM().getBytes() 会抛出NullPointerException。感谢您的帮助!

BOMInputStream 文档链接: https://commons.apache.org/proper/commons-io/javadocs/api-2.5/org/apache/commons/io/input/BOMInputStream.html

【问题讨论】:

    标签: java spring byte-order-mark


    【解决方案1】:

    没有布尔包含参数的构造函数排除了 BOM,因此hasBOM() 返回 false,并且不包含 BOM。并且字符串不会包含 BOM。 然后getBOM() 返回null!

    byte[] xml = requestDTO.getFile();
    int bomLength = 0;
    Charset charset = StandardCharsets.UTF_8;
    try (BOMInputStream bommedInputStream = new BOMInputStream(new ByteArrayInputStream(xml),
                true)) {
        if (bommedInputStream.hasBOM()) {
            bomLength = bommedInputStream.getBOM().length();
            charset = Charset.forName(bommedInputStream.getBOMCharsetName());
        } else {
            // Handle <?xml ... encoding="..." ... ?>.
            String t = new String(xml, StandardCharsets.ISO_8859_1));
            String enc = t.replace("(?sm).*<\\?xml.*\\bencoding=\"([^\"]+)\".*\\?>.*$", "$1");
            ... or such to fill charset ...
        }
    }
    String s = new String(xml, charset).replaceFirst("^\uFEFF", ""); // Remove BOM.
    validationService.validate(s);
    

    可以使用 bomLength 删除 BOM。 BOMInputStream 可以为我们提供许多 UTF 变体的字符集。

    没有编码/字符集(如您所用)的 String 构造函数将使用默认平台编码。由于 BOM 是 Unicode 代码指针 U+FEFF,您可以简单地传递 "\uFEFF"

    【讨论】:

    • 好的,知道了,以及如何在跳过 bom 后从 bomInputStream 中检索字符串/字节(如果找到的话)。
    • 第二个 BOMInputStream,如您所写,或者只是使用 BOM 长度在传递 ByteArrayInputStream 之前跳过这些字节。
    • 抱歉,不太明白。我的意思是如何从 bomInputStream 检索没有 BOM 的 xml 字节。据我了解,bomInputStream.getBOM().getBytes() 不会在没有 BOM 的情况下返回原始 xml
    • 将其添加到答案中。
    • 好的,现在明白了
    猜你喜欢
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2010-11-23
    相关资源
    最近更新 更多