繁体   English   中英

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

[英]How to read a specific line using the specific line number from a file in Java?

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

对于小文件:

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

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

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

如此有效,您只需阅读行,直到找到第 32 行。

不是我所知道的,但是您可以做的是使用 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(尽管可以说您可能不想引入新的依赖项只是为了这个,如果你发现它对其他东西也有用,它可能是有道理的)。

例如:

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)

您可以尝试indexed-file-reader (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]"));      

上面的例子读取一个由 50 行组成的文本文件,格式如下:

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

免责声明:我写了这个库

其它的办法。

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

尽管如其他答案中所述,如果不知道之前的偏移量(指针),则无法到达确切的行。 因此,我通过创建一个临时索引文件来实现这一点,该文件将存储每一行​​的偏移值。 如果文件足够小,您可以将索引(偏移量)存储在内存中,而无需单独的文件。

可以使用 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();

另请访问RandomAccessFile上的 Java 文档以获取更多信息:

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

注意:如果你想要在“32”行中的所有内容,你只需要调用readLine()也可以通过其他类“32”次。 如果您想多次获取特定行(当然基于行号),上述方法很有用。

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

在 Java 8 中,

对于小文件:

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

来源: 从文件中读取第 n 行

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

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

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

它对我有用:我结合了阅读简单文本文件的答案

但是我没有返回一个字符串,而是返回一个字符串的 LinkedList。 然后我可以选择我想要的行。

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

使用此代码:

import java.nio.file.Files;

import java.nio.file.Paths;

public class FileWork 
{

    public static void main(String[] args) throws IOException {

        String line = Files.readAllLines(Paths.get("D:/abc.txt")).get(1);

        System.out.println(line);  
    }

}

您还可以查看 LineNumberReader,BufferedReader 的子类。 除了 readline 方法,它还具有 setter/getter 方法来访问行号。 在从文件读取数据时跟踪读取的行数非常有用。

您可以使用 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);

}

EASY WAY - 使用行号读取一行。 假设行号从 1 开始,直到 null 。

public class TextFileAssignmentOct {
    
    private void readData(int rowNum, BufferedReader br) throws IOException {
        int n=1;                                    //Line number starts from 1
        String row;
        while((row=br.readLine()) != null)  {       // Reads every line
            if (n == rowNum) {                      // When Line number matches with which you want to read
                System.out.println(row);
            }
            n++;                                    //This increments Line number
        }
    }

    public static void main(String[] args) throws IOException {
        File f = new File("../JavaPractice/FileRead.txt");
        FileReader fr = new FileReader(f);
        BufferedReader br = new BufferedReader(fr);
        
        TextFileAssignmentOct txf = new TextFileAssignmentOct();
        txf.readData(4, br);    //Read a Specific Line using Line number and Passing buffered reader
    }
}
FileReader fr = new FileReader("new.txt");
        BufferedReader br = new BufferedReader(fr);
        for (lineNo = 1; lineNo < 10; lineNo++) {
            if (lineNo == 5) {
                line = br.readLine();
            } else
                br.readLine();

您可以使用 LineNumberReader 而不是 BufferedReader。 通过api。 您可以找到 setLineNumber 和 getLineNumber 方法。

他们都错了,我只是在大约 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; }}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM