流上字节的Java正则表达式替代



我的XML文件(用UTF-8编码)有两个问题:

  • 其中一些(不是全部)包含字节顺序标记EF BB BF

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

这两个问题都使我无法使用SAX解析器解析XML。我目前的方法是将文件读入字符串,并使用regex来提取这些字符并将字符串写回文件,这很好。然而,我的文件相当大(数百兆字节),每次调用replaceAll()时,将文件读入字符串并创建相同大小的结果字符串,很快导致java堆空间错误。

增加堆大小绝对不是一个长期的解决方案。我需要流式传输文件并动态提取所有这些字符。

关于一个有效的解决方案应该是什么样的,有什么建议吗?

我会将FilterInputStream子类化,以便在运行时过滤掉不需要的字节。

这个任务应该是相当容易的,因为字节顺序标记可能只在文件的开头(所以你只需要检查那里),空字节可以很容易地通过一个简单的==比较来过滤(不需要类似regex的功能)。

这很可能还会提高性能,因为您不需要在重新读取文件之前将完整的更正文件写入磁盘。

为什么不在将数据读入SAX解析器时过滤它呢?这样就不需要重写文件了。您可以覆盖FilterInputStream的read()方法来删除不需要的字节。

我想这就是@Joachim的意思。div;)

我只关注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()

相关内容

  • 没有找到相关文章

最新更新