大文件子串提取,避免行终止符

时间:2012-03-30 10:11:32

标签: java newline large-files

问题如下:

几个大文件(20 + MB)中都有DNA序列。我使用以下代码连接到这些文件:

fc = FileChannel.open(file);

// Create a read-only CharBuffer on the file
ByteBuffer bbuf = fc.map(FileChannel.MapMode.READ_ONLY, 0, 256);
CharBuffer cbuf = Charset.forName("8859_1").newDecoder().decode(bbuf);

我知道要提取的子序列的确切开始和结束位置,这将允许我使用该方法

cbuf.subSequence(start, end);

然而,大文件的行终止符会破坏DNA序列,它们会被视为一个字符。建议不要假定文件中行的固定宽度。什么是“跳过”行终止符的有效方法,但通过使用Charbuffer或类似的东西来保持内存效率?

我尝试过使用带有正则表达式的贪心量词,但行终止符再次破坏了结果。我想避免不惜一切代价完全加载文件内容。有没有办法将换行符视为“不存在”?

2 个答案:

答案 0 :(得分:0)

您可以阅读该文件,查找行终止符并存储其位置。

然后在提取时,您可以将没有终止符的位置转移到实际位置。

为了更快地转换,您可以预先计算偏移量,然后只搜索正确的偏移量(O(长n),其中n是行终止符的总数,与O(m)相比,其中m是您需要实际跳过的终结符的数量)

PS:如果可能发生的话,请考虑multichar(CR,LF)终结器。

答案 1 :(得分:0)

DNA序列不会创建类似“zillion”(大量)字节的文件吗?也许你应该避免加载整个文件,如果不需要?您似乎在变量cbuf中有一些数据(我不知道那些数据是什么;您的代码没有告诉)。我认为你可以写一个函数去除换行符,如:

int index = 0;
for(int i = 0; i < cbuf.length; i++)
{
   if(!cbuf[i] != '\n' && cbuf[i] != '\r')
   {
      cbuf[index] = cbuf[i];
      index++; // will only increase if not linebreak
   }
}

int newcbufLength = index + 1;

此函数将使用原始数组,因此您不会有新的(大?)数据副本。

(可能有错误,因为我最习惯使用C#而不是Java)