使用BufferedReader(Java)进行预读

时间:2016-01-06 14:30:10

标签: java parsing bufferedreader

我正在为这样的文件编写解析器:

LOCUS       SCU49845     5028 bp    DNA             PLN       21-JUN-1999
DEFINITION  Saccharomyces cerevisiae TCP1-beta gene, partial cds, and Axl2p
            (AXL2) and Rev7p (REV7) genes, complete cds.
ACCESSION   U49845
VERSION     U49845.1  GI:1293613

我希望获得某些标签(DEFINITION,VERSION等)之前的信息,但有些描述涵盖多行,我确实需要全部。使用BufferdReader读取我的文件时出现问题。 我几乎通过使用mark()和reset()来解决它,但在执行我的程序时,我注意到它只适用于一个标签,其他标签以某种方式被跳过。这是我到目前为止的代码:

Pattern pTag = Pattern.compile("^[A-Z]{2,}");//regex: 2 or more uppercase letters is a tag

Matcher mTagCurr = pTag.matcher(line);                

if (mTagCurr.find()) {
    reader.mark(1000);

    String nextLine = reader.readLine();
    Matcher mTagNext = pTag.matcher(nextLine);                    
    if (mTagNext.find()){
        reader.reset();
        continue;
    }

    Pattern pWhite = Pattern.compile("^\\s{6,}");
    Matcher mWhite = pWhite.matcher(nextLine);
    while (mWhite.find()) {
        line  = line.concat(nextLine);
    }                    
    System.out.println(line);
}

这段代码应该找到涵盖多行的标签和连接描述。我在这里找到的一些答案建议使用Scanner。这对我来说不是一个选择。我使用的文件可能非常大(我遇到的最大值是> 50GB)并且使用BufferedReader我希望减少对我的系统的压力。

2 个答案:

答案 0 :(得分:0)

我建议在单通道解析器中累积您获取的信息。在我怀疑的情况下,这将更简单,更快捷。

顺便说一下,你想缓存你的模式,因为创建它们非常昂贵。在某些情况下,你可能会发现你想要卵形完全使用它们。

答案 1 :(得分:0)

代码首先找到一个延续行,如果找不到它,则调用reset(),但是读取其他行的代码似乎没有这样做。它可以读取Genbank文件中另一部分的开头而不是把它放回去吗?我在这里看不到所有的循环控制代码,但我所看到的似乎是正确的。

如果所有其他方法都失败了,你需要一些简单的东西,那么总是BioJava(见How to Read a Genbank File with Biojava3并看看它是否有帮助)。我曾尝试将BioJava用于我自己的项目,但它总是有点短暂。

当我编写FASTA和FASTQ解析器时,我读入了bytechar缓冲区并以此方式处理它,但是有更多缓冲区管理代码要编写。这样,我不必担心将字节放回缓冲区。这也可以避免正则表达式,这在时间关键型应用程序中可能很昂贵。当然,这需要更多时间来实施。

提示:如果您自己管理缓冲区,为了获得最快的实施,请查看NIO(Java NIO Tutorial)。我看到在某些情况下放弃了10倍的加速(写入数据)。唯一的缺点是我还没有找到一种简单的方法来使用NIO读取gzip序列数据。