我正在读取一个文件,我不能一次缓冲所有的文件,因为它的大小从256MB到~2 2GB不等。
打开文件后,我将其中的一部分读入字节数组,将其转换为字符串并对其运行正则表达式,如果检测到该模式,则我的程序会记录下来。
我遇到的问题是,我的程序在文件中缺少了很多它应该检测模式的位置。
我90%确定的问题是,虽然模式在那里,但它并不完整,因为它超出了缓冲区的长度。我要查找的模式长度为8个字节,例如,模式的前4个字节位于数组中的最后4个位置;因此,当再次填充时,数组的前4个字节是模式的最后4个位置。因此,我的正则表达式总是失败。
我猜我需要做的是填充缓冲区,然后当它再次填充它时,将最后20个字节保留在其中,这样它就不会错过我正在寻找的任何模式。
任何建议都将不胜感激。提前谢谢。
托尼
发布于 2011-09-08 05:06:46
首先,不能将Java正则表达式应用于字节数组。您必须将其应用于String。因此,您必须将byte[]转换为String,并且您可能(a)使用了错误的编码,或者(b)截断了中间的字符串。
一旦你克服了这一点,你就需要使用流媒体学科来重新构建你所阅读的内容。我可以描述一个可能适用也可能不适用的方法:
将一大块数据读入缓冲区。在buffer.
如果这确实是一个普通的字符文件,则按如下方式修改:
Reader r = new InputStreamReader(inputByteStream, Charset.forName("utf-8"));然后应用上面的算法来避免缓冲区边界条件。
发布于 2011-09-08 05:04:17
你应该做什么的伪代码:
while true:
read 512 bytes into new buffer
if eof:
break
concatenate with previous buffer (and only previous buffer)
run regex on concatenated buffer发布于 2011-09-08 05:23:17
一个有趣的可能的解决方案是注意到正则表达式方法将输入作为CharSequence而不是String (据我所知,它们从不调用CharSequence.toString())。
因此,您可以实现一个从文件中提取字符的CharSequence,而无需将整个文件加载到内存中。如果您的文件采用一种编码方式,其中的字符采用恒定的字节数(ASCII 16),那么您几乎可以直接将RandomAccessFile调整为CharSequence (虽然我不确定这种情况下的性能,但您可能需要一些缓冲)。
https://stackoverflow.com/questions/7340482
复制相似问题