7

我有一个带有 utf8 编码的 xml。而这个文件包含BOM一个开头的文件。因此,在解析过程中,我遇到了 org.xml.sax.SAXParseException: Content is not allowed in prolog。我无法从文件中删除这 3 个字节。我无法将文件加载到内存中并在此处删除它们(文件很大)。因此,出于性能原因,我正在使用 SAX 解析器,如果它们出现在“”标记之前,则只想跳过这 3 个字节。我应该为此继承 InputStreamReader 吗?

我是java新手-请告诉我正确的方法。

4

3 回答 3

4

以前也出现过这种情况,当它发生在我身上时,我在 Stack Overflow 上找到了答案。链接的答案使用 aPushbackInputStream来测试 BOM。

于 2011-03-18T15:15:46.710 回答
3

我遇到了同样的问题,我用这段代码解决了这个问题:

private static InputStream checkForUtf8BOM(InputStream inputStream) throws IOException {
    PushbackInputStream pushbackInputStream = new PushbackInputStream(new BufferedInputStream(inputStream), 3);
    byte[] bom = new byte[3];
    if (pushbackInputStream.read(bom) != -1) {
        if (!(bom[0] == (byte) 0xEF && bom[1] == (byte) 0xBB && bom[2] == (byte) 0xBF)) {
            pushbackInputStream.unread(bom);
        }
    }
    return pushbackInputStream;
}
于 2011-03-18T15:17:53.530 回答
2
private static char[] UTF32BE = { 0x0000, 0xFEFF };
private static char[] UTF32LE = { 0xFFFE, 0x0000 };
private static char[] UTF16BE = { 0xFEFF };
private static char[] UTF16LE = { 0xFFFE };
private static char[] UTF8 = { 0xEFBB, 0xBF };

private static boolean removeBOM(Reader reader, char[] bom) throws Exception {
    int bomLength = bom.length;
    reader.mark(bomLength);
    char[] possibleBOM = new char[bomLength];
    reader.read(possibleBOM);
    for (int x = 0; x < bomLength; x++) {
        if ((int) bom[x] != (int) possibleBOM[x]) {
            reader.reset();
            return false;
        }
    }
    return true;
}

private static void removeBOM(Reader reader) throws Exception {
    if (removeBOM(reader, UTF32BE)) {
        return;
    }
    if (removeBOM(reader, UTF32LE)) {
        return;
    }
    if (removeBOM(reader, UTF16BE)) {
        return;
    }
    if (removeBOM(reader, UTF16LE)) {
        return;
    }
    if (removeBOM(reader, UTF8)) {
        return;
    }
}

用法:

// xml can be read from a file, url or string through a stream
URL url = new URL("some xml url");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
removeBOM(bufferedReader);
于 2013-05-06T08:40:59.133 回答