Как прочитать определенную строку, используя определенный номер строки из файла в Java?
Есть ли в Java какой-либо метод для чтения определенной строки из файла? Например, прочитайте строку 32 или любой другой номер строки.
19 ответов
Если у вас нет предыдущих знаний о строках в файле, невозможно получить прямой доступ к 32-й строке без чтения 31-й предыдущей строки.
Это верно для всех языков и всех современных файловых систем.
Таким образом, вы будете просто читать строки, пока не найдете 32-ю.
Решение Java 8:
Для небольших файлов:
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 строку, ничего не делая, используя функцию readline() BufferedReader
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 прав, и альтернативная реализация Криса (для небольших файлов только потому, что он загружает весь файл) может заключаться в использовании commons-io из Apache (хотя, возможно, вы не захотите вводить новую зависимость только для это, если вы найдете это полезным для других вещей, хотя, это может иметь смысл).
Например:
String line32 = (String) FileUtils.readLines(file).get(31);
http://commons.apache.org/io/api-release/org/apache/commons/io/FileUtils.html, java.lang.String)
Вы можете попробовать программу чтения индексированных файлов (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
Disclamer: я написал эту библиотеку
Хотя, как сказано в других ответах, невозможно получить точную строку, не зная смещение (указатель) раньше. Итак, я добился этого, создав временный индексный файл, в котором будут храниться значения смещения каждой строки. Если файл достаточно мал, вы можете просто сохранить индексы (смещение) в памяти, не требуя для этого отдельного файла.
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
Сложность: это O(n), поскольку он читает весь файл один раз. Пожалуйста, помните о требованиях к памяти. Если он слишком велик, чтобы быть в памяти, создайте временный файл, в котором будут храниться смещения вместо ArrayList, как показано выше.
Примечание: если все, что вы хотите в строке '32', вам просто нужно вызвать readLine(), также доступную через другие классы '32' раз. Вышеупомянутый подход полезен, если вы хотите получить определенную строку (на основе номера строки, конечно) несколько раз.
Спасибо!
По-другому.
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);
}
В 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. Пройдите через API. Вы можете найти методы setLineNumber и getLineNumber.
ЛЕГКИЙ СПОСОБ - чтение строки по номеру строки. Допустим, номер строки начинается с 1 до нуля.
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
}
}
для текстового файла вы можете использовать целое число с циклом, чтобы помочь вам получить номер строки, не забудьте импортировать классы, которые мы используем в этом примере.
File myObj = new File("C:\\Users\\LENOVO\\Desktop\\test.txt");//path of the file
FileReader fr = new FileReader(myObj);
fr.read();
BufferedReader bf = new BufferedReader(fr); //BufferedReader of the FileReader fr
String line = bf.readLine();
int lineNumber = 0;
while (line != null) {
lineNumber = lineNumber + 1;
if(lineNumber == 7)
{
//show line
System.out.println("line: " + lineNumber + " has :" + line);
break;
}
//lecture de la prochaine ligne, reading next
line = bf.readLine();
}
Вы также можете взглянуть на 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);
}
Они все не правы, я просто написал это примерно через 10 секунд. При этом мне удалось просто вызвать object.getQuestion("белья") в методе main, чтобы вернуть любую строку, которую я хочу.
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; }}