簡體   English   中英

Java 正則表達式替代 stream 上的字節

[英]Java regex alternative for bytes on stream

我有 XML 文件(以 UTF-8 編碼)有兩個問題:

  • 其中一些(不是全部)包含字節順序標記EF BB BF

  • 其中一些(不是全部)包含 Null 字符 00,分布在整個文件中。

這兩個問題都阻止我使用 SAX 解析器解析 XML。 我目前的方法是將文件讀入字符串並使用正則表達式來提取這些字符並將字符串寫回文件,效果很好。 但是,我的文件非常大(數百兆字節),並且每次調用 replaceAll() 時將文件讀入字符串並創建相同大小的結果字符串,很快就會導致 java 堆空間錯誤。

增加堆大小絕對不是一個長期的解決方案。 我需要 stream 文件並即時提取所有這些字符。

關於一個有效的解決方案應該是什么樣子的任何建議?

我會FilterInputStream以在運行時過濾掉不需要的字節。

該任務應該相當簡單,因為字節順序標記可能僅位於文件的開頭(因此您只需要檢查那里)並且可以通過簡單的==比較輕松地過濾 nul-bytes(不需要類似正則表達式的功能)。

這很可能還會提高性能,因為您無需在重新讀取之前將完整的更正文件寫出到磁盤。

為什么不將數據讀入 SAX 解析器時對其進行過濾。 這樣你就不需要重寫文件了。 您可以覆蓋 FilterInputStream 的 read() 方法以刪除您不想要的字節。

我認為這就是@Joachim 的建議。 ;)

我只關注 BOM,發現 null 字節的問題為時已晚。 我仍然將它作為補充發布,以防有人僅對 BOM 有問題。 請善待反對票。 :)


您可以使用支持mark()reset()InputStream讀取前三個字節,讀取前三個字節並在它們不是 BOM 時重置:

InputStream in = new BufferedInputStream(
        new FileInputStream(new File("xmlfile.xml")));
in.mark(3);
byte[] maybeBom = new byte[] {
        (byte) in.read(), (byte) in.read(), (byte) in.read() };

if(!Arrays.equals(maybeBom, new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF })) {
    in.reset();
}

我使用BufferedInputStream因為FileInputStream不支持mark()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM