如何使用Java中的文件中的特定行号读取特定行?

tri*_*ity 86 java file-io

在Java中,是否有任何方法可以从文件中读取特定行?例如,读取第32行或任何其他行号.

aio*_*obe 91

Java 8解决方案:

对于小文件:

String line32 = Files.readAllLines(Paths.get("file.txt")).get(32)
Run Code Online (Sandbox Code Playgroud)

对于大文件:

try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
    line32 = lines.skip(31).findFirst().get();
}
Run Code Online (Sandbox Code Playgroud)

  • "请注意,此方法适用于在单个操作中方便读取所有行的简单情况.它不适用于读取大文件." - Files.readAllLines()的Javadoc (3认同)

Joa*_*uer 69

除非您事先了解文件中的行,否则无法在不读取前31行的情况下直接访问第32行.

对于所有语言和所有现代文件系统都是如此.

如此有效,你只需阅读直到你找到第32行.

  • "先前的知识"可以像文件中的精确线条大小模式一样简单,因此您可以寻找某个位置. (3认同)
  • @Murali:当然.它也可以是行号到字节偏移的索引或其任何组合. (2认同)

Chr*_*son 38

不是我所知道的,但你可以做的是使用BufferedReader的readline()函数循环前31行无效

FileInputStream fs= new FileInputStream("someFile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
for(int i = 0; i < 31; ++i)
  br.readLine();
String lineIWant = br.readLine();
Run Code Online (Sandbox Code Playgroud)


Cha*_*ins 15

当然,Joachim是正确的,并且Chris的一个替代实现(对于小文件只因为它加载了整个文件)可能是使用来自Apache的commons-io(尽管可能你可能不想引入新的依赖关系)这个,如果你发现它对其他东西也很有用,那就有意义了).

例如:

String line32 = (String) FileUtils.readLines(file).get(31);
Run Code Online (Sandbox Code Playgroud)

http://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html#readLines(java.io.File,java.lang.String)

  • 虽然这会在转到第32行之前将整个文件加载到内存中,这对于大文件来说可能不实用,并且比读取util找到第32行要慢... (2认同)

jra*_*oyo 10

您可以尝试索引文件阅读器(Apache License 2.0).IndexedFileReader类有一个名为readLines(int from,int to)的方法,它返回一个SortedMap,其键是行号,值是读取的行.

例:

File file = new File("src/test/resources/file.txt");
reader = new IndexedFileReader(file);

lines = reader.readLines(6, 10);
assertNotNull("Null result.", lines);
assertEquals("Incorrect length.", 5, lines.size());
assertTrue("Incorrect value.", lines.get(6).startsWith("[6]"));
assertTrue("Incorrect value.", lines.get(7).startsWith("[7]"));
assertTrue("Incorrect value.", lines.get(8).startsWith("[8]"));
assertTrue("Incorrect value.", lines.get(9).startsWith("[9]"));
assertTrue("Incorrect value.", lines.get(10).startsWith("[10]"));      
Run Code Online (Sandbox Code Playgroud)

上面的示例按以下格式读取由50行组成的文本文件:

[1] The quick brown fox jumped over the lazy dog ODD
[2] The quick brown fox jumped over the lazy dog EVEN
Run Code Online (Sandbox Code Playgroud)

Disclamer:我写了这个库


rhe*_*ser 7

其它的办法。

try (BufferedReader reader = Files.newBufferedReader(
        Paths.get("file.txt"), StandardCharsets.UTF_8)) {
    List<String> line = reader.lines()
                              .skip(31)
                              .limit(1)
                              .collect(Collectors.toList());

    line.stream().forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)


小智 6

尽管如其他答案中所述,但是在不知道偏移量(指针)的情况下不可能到达确切的行。因此,我通过创建一个临时索引文件来实现此目的,该文件将存储每行的偏移值。如果文件足够小,则只需将索引(offset)存储在内存中,而无需使用单独的文件。

The offsets can be calculated by using the RandomAccessFile

    RandomAccessFile raf = new RandomAccessFile("myFile.txt","r"); 
    //above 'r' means open in read only mode
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    String cur_line = "";
    while((cur_line=raf.readLine())!=null)
    {
    arrayList.add(raf.getFilePointer());
    }
    //Print the 32 line
    //Seeks the file to the particular location from where our '32' line starts
    raf.seek(raf.seek(arrayList.get(31));
    System.out.println(raf.readLine());
    raf.close();
Run Code Online (Sandbox Code Playgroud)

另请访问Java文档以获取更多信息:https : //docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode

复杂度:这是O(n),因为它一次读取整个文件。请注意内存要求。如果太大而无法存储,则制作一个临时文件来存储偏移量,而不是存储ArrayList,如上所示。

注意:如果只想在'32'行中输入内容,则只需调用readLine()即可,其他类也可以使用'32'次。如果您想多次获得一条特定的线(基于路线数),上述方法很有用。

谢谢 !