Java阅读第n行

时间:2013-04-24 19:58:25

标签: java file-io

我正在尝试从文本文件中读取特定行,但是我不想将文件加载到内存中(它可能变得非常大)。

我一直在寻找,但我发现的每个例子都要求读取每一行(这会减慢我的代码,因为有超过100,000行)或者将整个事物加载到一个数组中并获得正确的元素(文件将具有很多行输入)。

我想做的一个例子:

String line = File.getLine(5);

“代码不是实际代码,它是为了显示我想要的原则”

有办法做到这一点吗?

- - - - - - - - 编辑

我刚刚意识到这个文件也会在读取行之间写入(添加到文件的末尾)。

8 个答案:

答案 0 :(得分:12)

  

有办法做到这一点吗?

除非每行都有固定的字节数,否则不是。

你不必实际保持内存中的每一行 - 但是你必须通读整个文件才能到达你想要的那一行,否则你将不知道在哪里开始阅读。

答案 1 :(得分:3)

必须逐行读取文件。否则你怎么知道什么时候你到了第5行(如你的例子)?

编辑:

您可能还想查看Random Access Files,如果您知道每行有多少字节,这可能会有所帮助,正如Jon Skeet所说。

答案 2 :(得分:3)

最简单的方法是使用BufferedReader(http://docs.oracle.com/javase/1.5.0/docs/api/java/io/BufferedReader.html),因为您可以指定缓冲区大小。你可以这样做:

BufferedReader in = new BufferedReader(new FileReader(“foo.in”),1024);

in.readLine();
in.readLine();
in.readLine();
in.readLine();
String line = in.readLine();

答案 3 :(得分:2)

  

1)读取用户选择的行

如果您只需要一次或不经常读取用户选择的行(或者文件足够小),那么您只需要从头开始逐行读取文件,直到您进入选定行线。

另一方面,如果需要经常读取用户选择的行,则应构建行号和偏移量的索引。因此,例如,第42行对应于文件中2347字节的偏移量。理想情况下,您只需读取整个文件一次并存储索引 - 例如,在地图中,使用行号作为键和偏移作为值。

  

2)读取自之后添加的新行   最后一次阅读。我计划每10秒读取一次文件。我有   行数,可以找到新的行号,但我需要   读那行

对于第二点,您可以简单地将当前偏移量保存到文件中,而不是保存当前行号 - 但如果它继续提供显着的性能优势,那么继续构建索引肯定不会受到影响。

  1. 使用RandomAccessFile.seek(长偏移)将文件指针设置为最近保存的偏移量(确认文件首先比最近保存的偏移量长 - 如果没有,则不会添加任何新的偏移量。)
  2. 使用RandomAccessFile.readLine()读取文件的一行
  3. 调用RandomAccessFile.getFilePointer()以在读取行后获取当前偏移量,并可选择将(currLineNo + 1,offset)放入索引中。
  4. 重复步骤2-3,直至到达文件末尾。
  5. 但是,除非性能已经成为问题或极有可能成为问题,否则不要过度使用性能优化。

答案 4 :(得分:0)

执行此操作的唯一方法是构建每行所在位置的索引(您只需要记录每行的结尾)如果没有从一开始就基于索引随机访问行的方法,您必须读取该行之前的每个字节。

BTW:在快速机器上读取100,000行可能只需要一秒钟。

答案 5 :(得分:0)

如果性能是一个很大的问题,并且你经常从静态文件中读取随机行,那么你可以通过读取文件并构建一个索引(基本上只是long[])来优化这一点。文件每一行的偏移量。

一旦你有了这个,你就知道在文件中准确跳转到哪里,然后你可以读到下一个换行符来检索整行。

答案 6 :(得分:0)

以下是我所拥有的一些代码片段,它将读取文件并将每第10行写入包括第一行到新文件(编写器)。您可以随时将try部分替换为您想要执行的任何操作。要更改要读取的行数,只需更改if语句中的0" lc.endsWith(" 0")"到你想读的任何一行。但是如果在读取文件时正在写入文件,则此代码仅在您运行此代码时才能使用文件中包含的数据。

            LineNumberReader  lnr = new LineNumberReader(new FileReader(new File(file)));
            lnr.skip(Long.MAX_VALUE);
            int linecount=lnr.getLineNumber();
            lnr.close();

        for (int i=0; i<=linecount; i++){

            //read lines
            String line = bufferedReader.readLine();
            String lc = String.valueOf(i);

            if (lc.endsWith("0")){

                try{

                    writer.append(line+"\n");
                    writer.flush();

                    }catch(Exception ee){
                }
            }
        }

答案 7 :(得分:0)

对于小文件:

String line = Files.readAllLines(Paths.get("file.txt")).get(n);

对于大文件:

String line;
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
    line = lines.skip(n).findFirst().get();
}

Java 7:

String line;
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    for (int i = 0; i < n; i++)
        br.readLine();
    line = br.readLine();
}

来源:Reading nth line from file