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

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

除非您对文件中的行有所了解,否则没有办法直接访问第32行,而无需读取以前的31行。

所有语言和所有现代文件系统都是如此。

所以有效地,你只需要读直到find第32行。

Java 8解决scheme:

对于小文件:

String line32 = Files.readAllLines(Paths.get("file.txt")).get(32) 

对于大文件:

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

不是我所知道的,但是你可以做的是通过使用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(); 

当然,Joachim是正确的,而Chris的一个替代实现(对于小文件只是因为它加载了整个文件)可能是使用Apache的commons-io(尽pipe可以说你可能不想引入一个新的依赖这个,如果你觉得它对其他的东西也有用的话,那可能是有道理的)。

例如:

 String line32 = (String) FileUtils.readLines(file).get(31); 

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

您可以尝试索引文件阅读器 (Apache许可证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]")); 

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

 [1] The quick brown fox jumped over the lazy dog ODD [2] The quick brown fox jumped over the lazy dog EVEN 

Disclamer:我写了这个库

如果你正在谈论一个文本文件,那么在没有读取所有行之前就没有办法做到这一点 – 毕竟,行是由换行符的存在决定的,所以它必须被读取。

使用支持readline的stream,只读取第一个X-1行并转储结果,然后处理下一个。

不,除非在该文件格式中,行长度是预先确定的(例如所有具有固定长度的行),否则必须逐行迭代来计算它们。

它适用于我:我已经结合阅读一个简单的文本文件的答案

但是,而不是返回一个string,我返回一个stringLinkedList。 然后,我可以select我想要的行。

 public static LinkedList<String> readFromAssets(Context context, String filename) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(context.getAssets().open(filename))); LinkedList<String>linkedList = new LinkedList<>(); // do reading, usually loop until end of file reading StringBuilder sb = new StringBuilder(); String mLine = reader.readLine(); while (mLine != null) { linkedList.add(mLine); sb.append(mLine); // process line mLine = reader.readLine(); } reader.close(); return linkedList; } 

虽然正如其他答案中所说的,但不可能在不知道偏移量(指针)之前到达确切的线路。 所以,我已经通过创build一个临时索引文件来存储每一行​​的偏移值。 如果文件足够小,则可以将索引(偏移量)存储在内存中,而不需要单独的文件。

 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(); 

有关更多信息,请访问java文档: https : //docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode

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

注意 :如果你想要的只是'32'行,你只需要调用readLine()也可以通过其他类的'32'次。 如果您想多次获取特定的行(基于行号),上述方法非常有用。

谢谢 !

您可以使用LineNumberReader而不是BufferedReader。 浏览api。 你可以findsetLineNumber和getLineNumber方法。

你也可以看看BufferedReader的子类LineNumberReader。 除readline方法外,还有setter / getter方法来访问行号。 从文件中读取数据时,非常有用地跟踪读取的行数。

 public String readLine(int line){ FileReader tempFileReader = null; BufferedReader tempBufferedReader = null; try { tempFileReader = new FileReader(textFile); tempBufferedReader = new BufferedReader(tempFileReader); } catch (Exception e) { } String returnStr = "ERROR"; for(int i = 0; i < line - 1; i++){ try { tempBufferedReader.readLine(); } catch (Exception e) { } } try { returnStr = tempBufferedReader.readLine(); } catch (Exception e) { } return returnStr; } 

其他方式。

 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); } 

您可以使用skip()函数跳过开头的行。

 public static void readFile(String filePath, long lineNum) { List<String> list = new ArrayList<>(); long totalLines, startLine = 0; try (Stream<String> lines = Files.lines(Paths.get(filePath))) { totalLines = Files.lines(Paths.get(filePath)).count(); startLine = totalLines - lineNum; // Stream<String> line32 = lines.skip(((startLine)+1)); list = lines.skip(startLine).collect(Collectors.toList()); // lines.forEach(list::add); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } list.forEach(System.out::println); } 

他们都是错误的,我只是在10秒左右写了这个。 有了这个,我设法在main方法中调用object.getQuestion(“linenumber”)来返回我想要的任何行。

 public class Questions { File file = new File("Question2Files/triviagame1.txt"); public Questions() { } public String getQuestion(int numLine) throws IOException { BufferedReader br = new BufferedReader(new FileReader(file)); String line = ""; for(int i = 0; i < numLine; i++) { line = br.readLine(); } return line; }}