如何读取文本文件中指定数量的行?

时间:2016-07-12 07:00:32

标签: java file-io

我在JAVA中读取更大的文件时遇到问题。我以前读过的文件大小为 750MB 所以当我以前用 BufferedReader 扫描仪 LineNumberReader读取文件时都无法阅读并导致 OutOfMemoryError

有没有简单的方法来阅读更大的文件?是否有任何方法可以跳过一些行并在跳过行后读取特定的行。

我用来读取文件的代码:

FileInputStream inputStream = null;
Scanner sc = null;
try
{
     inputStream = new FileInputStream(path);
     sc = new Scanner(inputStream, "UTF-8");
     while (sc.hasNextLine())
     {
          String line = sc.nextLine();
     }     
     if (sc.ioException() != null)
     {
         throw sc.ioException();
     }
}
finally
{
     inputStream.close();
     sc.close();
}

例如:

如果我想从 1001到2000 读取多行,我怎样才能从那个更大尺寸的文件中读取这些特定的行。

提前致谢。

1 个答案:

答案 0 :(得分:0)

问题是知道一条线的终点。如果不查看该文件,这根本不可能。没有此类功能可让您阅读特定行号。如果您询问了某个字节位置,则答案为java.io.RandomAccessFile

所以你有两个选择:

  1. 每当您想要读取某个行号时,请创建一个新的 BufferedReader (以及基础流)并跳过所有行,直到找到所需的行。顾名思义,BufferedReader以4096个字符的块为单位缓冲输入源 - 8192个字节。这应该足以满足大多数目的。
  2. 如果第一个选项太慢而无法达到您的目的(例如,您必须每秒读取多次),请为您的文件编制索引。我的意思是:创建一个新的 RandomAccessFile ,搜索所有出现的换行符并记住它们的字节偏移量。每次要读取某一行时,只需反向查找字节偏移量。您可以使用一个int数组,其中索引是行号。这导致查找的时间复杂度为O(1)。但是要小心:如果文件在索引后发生更改,则所有字节偏移都将失效。所以你必须再次索引文件。
  3. 编辑:第二个选项要求文件不包含空行。在这种情况下,lookup-array也会触发 OutOfMemoryError 。每个java int需要4个字节。如果我们假设写入文件的换行符至少需要1个字节,则因子为4.因此,当索引750 MB大文件时,该阵列至少需要4 * 750 MB = 3 GB。因此,您必须使用命令行选项-Xmx扩展JVM堆。

    第二次编辑:如上所述piet.t,如果文件只包含一行,则还必须使用命令行选项-Xmx扩大JVM堆。