Java:什么是读取相对较大的txt文件并存储其数据的最有效方法?

时间:2014-10-22 18:19:29

标签: java string memory

我本来应该写一个读取DNA序列的方法,以测试它上面的一些字符串匹配算法。

我使用了一些现有的代码来读取文本文件(实际上并不了解其他文件):

try {
    FileReader fr = new FileReader(file);
    BufferedReader br = new BufferedReader(fr);

    while((line = br.readLine()) != null) {
        seq += line;
    }

    br.close();
}
catch(FileNotFoundException e) { e.printStackTrace(); }
catch(IOException e) { e.printStackTrace(); }

对于包含大约3000个字符的小文本文件,这似乎很好用,但是需要永远(我只是在10分钟后取消它)来读取包含超过4500万个字符的文件。

有更有效的方法吗?

3 个答案:

答案 0 :(得分:6)

我注意到的一件事是你在做seq + = line。 seq可能是一个字符串?如果是这样,那么你必须记住字符串是不可变的。所以实际上你每次尝试在它上面添加一行时都会创建一个新的String。请改用StringBuilder。此外,如果可能,您不想创建字符串然后处理。那样你必须做两次。理想情况下,您希望在阅读时进行处理,但我不了解您的情况。

答案 1 :(得分:1)

减缓进度的主要因素是"连接"当你调用seq + = line时,字符串seq和行。我使用引号进行连接,因为在Java中,一旦创建了字符串就无法修改(例如,提到的用户1598503是不可变的)。最初,这不是一个问题,因为字符串很小,但是一旦字符串变得很长,e.e。数十万个字符,必须为新String重新分配内存,这需要相当多的时间。 StringBuilder将允许您在适当的位置进行这些连接,这意味着您不会每次都创建一个新的对象。

答案 2 :(得分:1)

你的问题不在于阅读需要花费太多时间,但连接需要花费太多时间。只是为了验证这一点,我运行了你的代码(没有完成),然后只是简单地描述了第8行(seq + = line),并在一秒钟内运行。您可以尝试使用seq = seq.concat(line),因为据报道它在大多数情况下速度相当快,但我也试过了,并且在1-2分钟内没有运行(对于9.6mb输入文件)。我的解决方案是将您的行存储在ArrayList(或您选择的容器)中。 ArrayList示例使用相同的输入文件在大约2-3秒内工作。 (所以你的while循环的内容是list.add(line);)。如果你真的,真的想将整个文件存储在一个字符串中,你可以做这样的事情(使用Scanner类):

String content = new Scanner(new File("input")).useDelimiter("\\Z").next();

^^这也可以在几秒钟内完成。我应该提到" \ Z"是文件分隔符的结尾,这就是为什么它一下子读完整个东西。