У Java існує спосіб читання певного рядка з файлу? Наприклад, прочитайте рядок 32 або будь-який інший номер рядка.
У Java існує спосіб читання певного рядка з файлу? Наприклад, прочитайте рядок 32 або будь-який інший номер рядка.
Відповіді:
Якщо у вас немає попередніх знань про рядки у файлі, немає можливості безпосередньо отримати доступ до 32-го рядка, не прочитавши 31 попередній рядок.
Це справедливо для всіх мов та всіх сучасних файлових систем.
Так ефективно ви просто будете читати рядки, поки не знайдете 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 рядок, не роблячи нічого, використовуючи функцію 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();
Звичайно, Йоахім правий, і альтернативною реалізацією 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 , 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#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);
}
Якщо ви говорите про текстовий файл, то насправді неможливо це зробити, не прочитавши всі рядки, що передують йому - Зрештою, рядки визначаються наявністю нового рядка, тому його доводиться читати.
Використовуйте потік, який підтримує лінію зчитування, і просто прочитайте перші рядки X-1 і скиньте результати, а потім обробіть наступний.
У 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-го рядка з файлу
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.
Ви також можете поглянути на 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 ("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; }}