2011-03-18 4 views
5

xml에 utf8 인코딩이 있습니다. 그리고이 파일은 BOM에 파일의 시작을 포함합니다. 그래서 파싱하는 동안 org.xml.sax.SAXParseException이 발생했습니다 : 프롤로그에서는 내용이 허용되지 않습니다. 파일에서 3 바이트를 제거 할 수 없습니다. 파일을 메모리로로드 할 수 없으며 여기에서 파일을 제거 할 수 없습니다 (파일 크기가 큽니다). 퍼포먼스상의 이유로 SAX 파서를 사용하고 있고 그 전에 ""태그가 있다면 그 3 바이트를 건너 뛰고 싶습니다. 이것을 위해 InputStreamReader를 상속해야합니까?org.apache.xerces.parsers.SAXParser가 utf8로 인코딩 된 XML에서 BOM을 건너 뛰지 않는 이유는 무엇입니까?

저는 java에서 새로운입니다. 제발 옳은 길을 보여주세요.

+0

[바이트 순서 표시 나사의 중복 가능성까지 파일 읽기 자바에서] (http://stackoverflow.com/questions/1835430/byte-order-mark-screws-up-file-reading-in-java) –

답변

4

이 문제는 이전에 발생했으며 스택 오버플로가 발생했을 때 the answer이 발생했습니다. 연결된 대답은 PushbackInputStream을 사용하여 BOM을 테스트합니다.

1

저도 같은 문제가 발생했는데이 코드와 그것을 해결했습니다

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; 
} 
+0

이것은 UTF8에 대한 ... 나는 UTF16 다를 것이라고 가정 그것의 단지 2 바이트)? – Trinition

+0

늦게까지 죄송합니다. 예, UTF16에는 BEM이 2 바이트 만 있습니다. 0xFE 0xFF (빅 엔디안) 또는 0xFF 0xFE (리틀 엔디안)입니다. – javanna

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