Em Java, existe algum método para ler uma linha específica de um arquivo? Por exemplo, leia a linha 32 ou qualquer outro número de linha.
Em Java, existe algum método para ler uma linha específica de um arquivo? Por exemplo, leia a linha 32 ou qualquer outro número de linha.
Respostas:
A menos que você tenha conhecimento prévio sobre as linhas do arquivo, não há como acessar diretamente a 32ª linha sem ler as 31 linhas anteriores.
Isso é verdade para todas as linguagens e todos os sistemas de arquivos modernos.
De forma eficaz, você simplesmente lerá as linhas até encontrar a 32ª.
Para arquivos pequenos:
String line32 = Files.readAllLines(Paths.get("file.txt")).get(32)
Para arquivos grandes:
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line32 = lines.skip(31).findFirst().get();
}
Não que eu saiba, mas o que você poderia fazer é percorrer as primeiras 31 linhas sem fazer nada usando a função readline () do 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 está certo, é claro, e uma implementação alternativa para Chris (para arquivos pequenos apenas porque carrega o arquivo inteiro) pode ser usar o commons-io do Apache (embora você possa não querer introduzir uma nova dependência apenas para isso, se você achar que é útil para outras coisas também, pode fazer sentido).
Por exemplo:
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)
Você pode tentar o leitor de arquivos indexados (Licença Apache 2.0). A classe IndexedFileReader tem um método chamado readLines (int from, int to) que retorna um SortedMap cuja chave é o número da linha e o valor é a linha lida.
Exemplo:
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]"));
O exemplo acima lê um arquivo de texto composto por 50 linhas no seguinte formato:
[1] The quick brown fox jumped over the lazy dog ODD
[2] The quick brown fox jumped over the lazy dog EVEN
Disclamer: Eu escrevi esta biblioteca
Embora como dito em outras respostas, não é possível chegar à linha exata sem saber o deslocamento (ponteiro) antes. Portanto, consegui isso criando um arquivo de índice temporário que armazenaria os valores de deslocamento de cada linha. Se o arquivo for pequeno o suficiente, você pode simplesmente armazenar os índices (deslocamento) na memória sem precisar de um arquivo separado para ele.
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();
Visite também os documentos java para obter mais informações: https://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html#mode
Complexidade : Este é O (n), pois lê o arquivo inteiro uma vez. Esteja ciente dos requisitos de memória. Se for muito grande para estar na memória, crie um arquivo temporário que armazene os deslocamentos em vez de ArrayList como mostrado acima.
Nota : Se tudo o que você quiser na linha '32', basta chamar o readLine () também disponível em outras classes '32' vezes. A abordagem acima é útil se você deseja obter uma linha específica (com base no número da linha, é claro) várias vezes.
Obrigado !
Outra maneira.
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);
}
Se você está falando sobre um arquivo de texto, então realmente não há como fazer isso sem ler todas as linhas que o precedem - Afinal, as linhas são determinadas pela presença de uma nova linha, então ela deve ser lida.
Use um fluxo que suporte readline e apenas leia as primeiras linhas X-1 e despeje os resultados, em seguida, processe o próximo.
Em Java 8,
Para arquivos pequenos:
String line = Files.readAllLines(Paths.get("file.txt")).get(n);
Para arquivos grandes:
String line;
try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {
line = lines.skip(n).findFirst().get();
}
Em 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();
}
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;
}
Funciona para mim: combinei a resposta de Lendo um arquivo de texto simples
Mas em vez de retornar uma String, estou retornando uma LinkedList of Strings. Então, posso selecionar a linha que desejo.
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;
}
Use este código:
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);
}
}
Você pode usar LineNumberReader em vez de BufferedReader. Vá até a API. Você pode encontrar os métodos setLineNumber e getLineNumber.
Você também pode dar uma olhada em LineNumberReader, subclasse de BufferedReader. Junto com o método readline, ele também possui métodos setter / getter para acessar o número da linha. Muito útil para controlar o número de linhas lidas, enquanto lê os dados do arquivo.
você pode usar a função skip () para pular as linhas desde o início.
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);
}
Eles estão todos errados. Acabei de escrever isso em cerca de 10 segundos. Com isso, consegui chamar apenas o object.getQuestion ("linho") no método principal para retornar a linha que eu quiser.
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; }}