为什么org.apache.xerces.parsers.SAXParser不会跳过utf8编码的xml中的BOM?

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

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

之前已经出现了,当我遇到它时,我在Stack Overflow上找到了答案 。 链接的答案使用PushbackInputStream来测试BOM。

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

 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; } 
 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);