Czy w Javie jest jakaś metoda odczytu określonego wiersza z pliku? Na przykład przeczytaj wiersz 32 lub inny numer wiersza.
Czy w Javie jest jakaś metoda odczytu określonego wiersza z pliku? Na przykład przeczytaj wiersz 32 lub inny numer wiersza.
Odpowiedzi:
Jeśli nie masz wcześniejszej wiedzy na temat wierszy w pliku, nie ma możliwości bezpośredniego dostępu do 32. linii bez przeczytania 31 poprzednich wierszy.
Dotyczy to wszystkich języków i wszystkich nowoczesnych systemów plików.
Tak efektywnie będziesz po prostu czytać wiersze, aż znajdziesz 32..
W przypadku małych plików:
String line32 = Files.readAllLines(Paths.get("file.txt")).get(32)
W przypadku dużych plików:
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line32 = lines.skip(31).findFirst().get();
}
Nie żebym o tym wiedział, ale co możesz zrobić, to pętla przez pierwsze 31 linii, nie robiąc nic za pomocą funkcji 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 jest oczywiście włączony, a alternatywną implementacją dla Chrisa (tylko dla małych plików, ponieważ ładuje cały plik) może być użycie commons-io z Apache (chociaż prawdopodobnie nie chcesz wprowadzać nowej zależności tylko dla jeśli jednak uznasz to za przydatne również do innych rzeczy, może to mieć sens).
Na przykład:
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)
Możesz wypróbować program indexed-file-reader (Apache License 2.0). Klasa IndexedFileReader ma metodę o nazwie readLines (int from, int to), która zwraca SortedMap, którego kluczem jest numer wiersza, a wartością jest odczytany wiersz.
Przykład:
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]"));
Powyższy przykład odczytuje plik tekstowy złożony z 50 wierszy w następującym formacie:
[1] The quick brown fox jumped over the lazy dog ODD
[2] The quick brown fox jumped over the lazy dog EVEN
Disclamer: Napisałem tę bibliotekę
Chociaż, jak powiedziano w innych odpowiedziach, nie jest możliwe dotarcie do dokładnej linii bez wcześniejszej znajomości przesunięcia (wskaźnika). Tak więc osiągnąłem to, tworząc tymczasowy plik indeksu, który będzie przechowywać wartości przesunięcia każdej linii. Jeśli plik jest wystarczająco mały, możesz po prostu przechowywać indeksy (przesunięcie) w pamięci bez potrzeby oddzielnego pliku.
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();
Odwiedź również dokumentację java, aby uzyskać więcej informacji: https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode
Złożoność : to jest O (n), ponieważ odczytuje cały plik raz. Należy pamiętać o wymaganiach dotyczących pamięci. Jeśli jest zbyt duży, aby przechowywać go w pamięci, utwórz plik tymczasowy, który przechowuje przesunięcia zamiast ArrayList, jak pokazano powyżej.
Uwaga : Jeśli chcesz mieć wszystko w linii „32”, wystarczy wywołać funkcję readLine (), która jest dostępna również dla innych klas „32” razy. Powyższe podejście jest przydatne, jeśli chcesz uzyskać określoną linię (w oparciu o numer linii oczywiście) wiele razy.
Dzięki !
Inny sposób.
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);
}
Jeśli mówisz o pliku tekstowym, to naprawdę nie ma sposobu na zrobienie tego bez przeczytania wszystkich linii, które go poprzedzają - w końcu linie są określane przez obecność nowej linii, więc należy ją przeczytać.
Użyj strumienia obsługującego readline i po prostu przeczytaj pierwsze wiersze X-1 i zrzuć wyniki, a następnie przetwórz następny.
W Javie 8
W przypadku małych plików:
String line = Files.readAllLines(Paths.get("file.txt")).get(n);
W przypadku dużych plików:
String line;
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line = lines.skip(n).findFirst().get();
}
W Javie 7
String line;
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
for (int i = 0; i < n; i++)
br.readLine();
line = br.readLine();
}
Źródło: odczyt n-tej linii z pliku
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;
}
U mnie to działa: połączyłem odpowiedź Czytanie prostego pliku tekstowego
Ale zamiast zwracać String, zwracam LinkedList of Strings. Następnie mogę wybrać żądaną linię.
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;
}
Użyj tego kodu:
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);
}
}
Możesz użyć LineNumberReader zamiast BufferedReader. Przejdź przez interfejs API. Możesz znaleźć metody setLineNumber i getLineNumber.
Możesz również przyjrzeć się LineNumberReader, podklasie BufferedReader. Wraz z metodą readline posiada również metody setter / getter umożliwiające dostęp do numeru linii. Bardzo przydatne do śledzenia liczby czytanych wierszy podczas odczytywania danych z pliku.
możesz użyć funkcji skip (), aby pominąć linie od początku.
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 - Czytanie linii za pomocą numeru linii. Powiedzmy, że numer linii zaczyna się od 1 do zera.
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
}
}
Wszyscy się mylą. Napisałem to w około 10 sekund. Dzięki temu udało mi się po prostu wywołać object.getQuestion ("numer linii") w głównej metodzie, aby zwrócić dowolną linię.
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; }}