В Java существует ли какой-либо метод для чтения определенной строки из файла? Например, прочитайте строку 32 или любой другой номер строки.
Как читать определенную строку, используя определенный номер строки из файла на Java?
Ответ 1
Если у вас нет прежних знаний о строках в файле, нет способа прямого доступа к 32-й строке без чтения 31 предыдущей строки.
Это верно для всех языков и всех современных файловых систем.
Таким образом, вы просто будете читать строки, пока не найдете 32-й.
Ответ 2
Решение 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();
}
Ответ 3
Не то, что я знаю, но то, что вы могли бы сделать, это цикл через первые 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();
Ответ 4
Йоахим прав, и альтернативная реализация Крису (для небольших файлов только потому, что он загружает весь файл), возможно, будет использовать commons-io из Apache (хотя, возможно, вы, возможно, не захотите вводить новую зависимость только для этого, если вы сочтете это полезным для других вещей, хотя, это может иметь смысл).
Например:
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)
Ответ 5
Вы можете попробовать 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
Disclamer: я написал эту библиотеку
Ответ 6
Нет, если в этом формате файла не заданы длины строк (например, все строки с фиксированной длиной), вам нужно будет перебирать строки за строкой, чтобы подсчитать их.
Ответ 7
Если вы говорите о текстовом файле, то нет никакого способа сделать это, не читая все строки, предшествующие ему. В конце концов, строки определяются наличием новой строки, поэтому ее нужно читать.
Используйте поток, поддерживающий readline, и просто прочитайте первые строки X-1 и дамп результатов, затем обработайте следующий.
Ответ 8
Хотя, как сказано в других ответах, невозможно получить точную строку, не зная смещения (указатель) раньше. Итак, я достиг этого, создав временный индексный файл, который сохранит значения смещения каждой строки. Если файл достаточно мал, вы можете просто сохранить индексы (смещение) в памяти, не требуя для этого отдельного файла.
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), когда он читает весь файл один раз. Обратите внимание на требования к памяти. Если он слишком большой, чтобы быть в памяти, тогда создайте временный файл, в котором хранятся смещения вместо ArrayList, как показано выше.
Примечание. Если вы хотите в строке "32", вам просто нужно вызвать readLine(), также доступную через 32-х классы других классов. Вышеупомянутый подход полезен, если вы хотите получить определенную строку (на основе номера строки, конечно) несколько раз.
Спасибо!
Ответ 9
Это работает для меня: Я объединил ответ Чтение простого текстового файла
Но вместо возврата String я возвращаю 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;
}
Ответ 10
Другой способ.
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);
}
Ответ 11
Вы можете использовать LineNumberReader вместо BufferedReader. Пройдите через api. Вы можете найти методы setLineNumber и getLineNumber.
Ответ 12
Вы также можете взглянуть на LineNumberReader, подкласс BufferedReader. Наряду с методом readline у него также есть методы setter/getter для доступа к номеру строки. Очень полезно отслеживать количество строк, прочитанных при чтении данных из файла.
Ответ 13
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;
}
Ответ 14
вы можете использовать функцию 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);
}
Ответ 15
Они все ошибаются, я написал это примерно через 10 секунд. С этим мне удалось просто вызвать 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; }}