Как прочитать конкретную строку, используя конкретный номер строки из файла в Java?
в Java, есть ли способ, чтобы прочитать определенную строку из файла? Например, прочитайте строку 32 или любой другой номер строки.
17 ответов:
Если у вас нет предыдущих знаний о строках в файле, нет никакого способа напрямую получить доступ к 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, конечно, прав, и альтернативная реализация Chris' (для небольших файлов только потому, что он загружает весь файл) может заключаться в использовании 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- Ява.ленг.Строка)
можно попробовать indexed-file-reader (Лицензия 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]"));
[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 docs для получения дополнительной информации информация: https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode
сложности: Это 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); }
Если вы говорите о текстовом файле, то на самом деле нет способа сделать это без чтения всех строк, которые ему предшествуют - в конце концов, строки определяются наличием новой строки, поэтому ее нужно читать.
используйте поток, который поддерживает readline, и просто прочитайте первые строки X-1 и сбросьте результаты, а затем обработайте следующий.
это работает для меня: Я объединил ответ чтение простого текстового файла
но вместо того, чтобы возвращать строку, я возвращаюсь в 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; }
В 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-й строки из файла
используйте этот код:
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.
вы также можете взглянуть на LineNumberReader, подкласс BufferedReader. Наряду с методом 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; }
вы можете использовать функцию 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 секунд. С этим мне удалось просто вызвать объект.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; }}