使用 BOMInputStream 跳过 BOM 并在没有 BOM 的情况下检索 byte[]

Skip BOM using BOMInputStream and retrieve byte[] without BOM

我有一个带有 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()returnsfalse。第二个,我不确定稍后如何从 bomInputStream 中检索 byte[],因为 bomInputStream.getBOM().getBytes() 会抛出 NullPointerException。感谢您的帮助!

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

不带boolean include参数的构造函数不包含BOM,因此hasBOM() returns false,不包含BOM。并且字符串将不包含 BOM。 然后 getBOM() returns 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=\"([^\"]+)\".*\?>.*$", "");
        ... or such to fill charset ...
    }
}
String s = new String(xml, charset).replaceFirst("^\uFEFF", ""); // Remove BOM.
validationService.validate(s);

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

不带 encoding/charset 的 String 构造函数(如您所用)将使用默认平台编码。由于BOM是Unicode代码指针U+FEFF,所以直接传"\uFEFF".

即可