Sem loops: {{{Scanner sc = novo Scanner (arquivo, "UTF-8"); sc.useDelimiter ("$ ^"); // regex que não corresponde a nada String text = sc.next (); sc.close (); }}}
Aivar 28/04
3
é tão interessante que não há nada como "read ()" em python, para ler todo o arquivo para uma string
ASCII é um arquivo de texto que você usaria Readerspara ler. Java também suporta a leitura de um arquivo binário usando InputStreams. Se os arquivos que estão sendo lidos forem grandes, você poderá usar umBufferedReader em cima de um FileReaderpara melhorar o desempenho da leitura.
Escolher um leitor realmente depende do conteúdo para o qual você precisa. Se o arquivo é pequeno (ish) e você precisa de tudo, é mais rápido (comparado a nós: 1.8-2x) usar apenas um FileReader e ler tudo (ou pelo menos pedaços grandes o suficiente). Se você estiver processando linha por linha, vá para o BufferedReader.
Vlad
3
A ordem das linhas será preservada ao usar "Files.lines (..). ForEach (...)". Meu entendimento é que a ordem será arbitrária após esta operação.
Daniil Shevelev 14/09/14
39
Files.lines(…).forEach(…)não preserva a ordem das linhas, mas é executado em paralelo, @Dash. Se o pedido for importante, você pode usá-lo Files.lines(…).forEachOrdered(…), o que deve preservar o pedido (embora não tenha sido verificado).
Palec 15/02
2
@Palec isso é interessante, mas você pode citar os documentos onde diz que Files.lines(...).forEach(...)é executado em paralelo? Eu pensei que este era apenas o caso quando você explicitamente faz o fluxo paralelo usando Files.lines(...).parallel().forEach(...).
Klitos Kyriacou 9/11
3
Minha formulação original não é à prova de balas, @KlitosKyriacou. O ponto é que forEachnão garante nenhuma ordem e o motivo é a fácil paralelização. Se a ordem deve ser preservada, use forEachOrdered.
Palec
687
Minha maneira favorita de ler um arquivo pequeno é usar um BufferedReader e um StringBuilder. É muito simples e direto ao ponto (embora não seja particularmente eficaz, mas bom o suficiente para a maioria dos casos):
BufferedReader br =newBufferedReader(newFileReader("file.txt"));try{StringBuilder sb =newStringBuilder();String line = br.readLine();while(line !=null){
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();}String everything = sb.toString();}finally{
br.close();}
Alguns salientaram que após o Java 7 você deve usar os recursos try-with-resources (isto é, fechamento automático):
try(BufferedReader br =newBufferedReader(newFileReader("file.txt"))){StringBuilder sb =newStringBuilder();String line = br.readLine();while(line !=null){
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();}String everything = sb.toString();}
Quando leio seqüências de caracteres como essa, geralmente quero manipular algumas linhas por linha de qualquer maneira, então vou para essa implementação.
Embora, se eu realmente queira apenas ler um arquivo em uma String, sempre usei o Apache Commons IO com o método da classe IOUtils.toString (). Você pode dar uma olhada na fonte aqui:
try(FileInputStream inputStream =newFileInputStream("foo.txt")){String everything =IOUtils.toString(inputStream);// do something with everything string}
Fiz um pequeno ajuste para parar de adicionar uma nova linha (\ n) se a última linha for alcançada. code while (linha! = nula) {sb.append (linha); line = br.readLine (); // Adicione apenas uma nova linha quando a linha de curvatura NÃO for a última linha. If (line! = Null) {sb.append ("\ n"); }}code
Ramon Fincken 16/04
2
Semelhante ao Apache IO IOUtils comuns # toString () é sun.misc.IOUtils # readFully (), incluído nos JREs do Sun / Oracle.
Gb96
3
Para um desempenho sempre chamar sb.append ( '\ n') em detrimento de sb.append ( "\ n") como um char é anexado ao StringBuilder mais rápido do que uma String
GB96
2
FileReader pode lançar FileNotFoundException e BufferedRead pode lançar IOException para que você precise capturá-los.
A maneira mais fácil é usar a Scannerclasse em Java e o objeto FileReader. Exemplo simples:
Scanner in =newScanner(newFileReader("filename.txt"));
Scanner possui vários métodos para leitura de strings, números, etc ... Você pode procurar mais informações sobre isso na página de documentação do Java.
ou use a tentativa "try-with-resources" (FileReader reader = new FileReader (file))
Hernán Eche
3
Notei o file.length (), como isso funciona com arquivos utf-16?
Wayne
5
Essa técnica assume que read () preenche o buffer; que o número de caracteres é igual ao número de bytes; que o número de bytes cabe na memória; e que o número de bytes se encaixa em um número inteiro. -1
Marquês de Lorne
1
@HermesTrismegistus Forneci quatro razões pelas quais está errado. StefanReich está perfeitamente correto em concordar comigo.
Marquês de Lorne
35
Eu tive que avaliar as diferentes maneiras. Vou comentar minhas descobertas, mas, em resumo, a maneira mais rápida é usar um BufferedInputStream antigo simples sobre um FileInputStream. Se muitos arquivos precisarem ser lidos, três threads reduzirão o tempo total de execução para aproximadamente a metade, mas a adição de mais threads diminuirá progressivamente o desempenho até que demore três vezes mais para concluir com vinte threads do que com apenas um thread.
A suposição é que você deve ler um arquivo e fazer algo significativo com seu conteúdo. Nos exemplos a seguir, está lendo linhas de um log e conte as que contêm valores que excedem um determinado limite. Portanto, estou assumindo que o Java 8 de Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";"))uma linha não é uma opção.
Testei em Java 1.8, Windows 7 e unidades SSD e HDD.
Eu escrevi seis implementações diferentes:
rawParse : use BufferedInputStream sobre um FileInputStream e, em seguida, corte linhas lendo byte a byte. Isso superou qualquer outra abordagem de thread único, mas pode ser muito inconveniente para arquivos não ASCII.
lineReaderParse : use um BufferedReader sobre um FileReader, leia linha por linha, divida as linhas chamando String.split (). Isso é aproximadamente 20% mais lento que rawParse.
lineReaderParseParallel : É o mesmo que lineReaderParse, mas usa vários threads. Essa é a opção mais rápida em todos os casos.
nioFilesParse : use java.nio.files.Files.lines ()
nioAsyncParse : use um AsynchronousFileChannel com um manipulador de conclusão e um conjunto de encadeamentos.
nioMemoryMappedParse : use um arquivo mapeado na memória. Essa é realmente uma péssima idéia, gerando tempos de execução pelo menos três vezes maiores do que qualquer outra implementação.
Estes são os tempos médios para a leitura de 204 arquivos de 4 MB cada, em uma unidade i7 e SSD de quatro núcleos. Os arquivos são gerados em tempo real para evitar o cache do disco.
Encontrei uma diferença menor do que eu esperava entre a execução em um SSD ou uma unidade de disco rígido, sendo o SSD aproximadamente 15% mais rápido. Isso pode ocorrer porque os arquivos são gerados em um disco rígido não fragmentado e são lidos sequencialmente; portanto, a unidade rotativa pode funcionar quase como um SSD.
Fiquei surpreso com o baixo desempenho da implementação nioAsyncParse. Eu implementei algo da maneira errada ou a implementação de vários threads usando o NIO e um manipulador de conclusão executa o mesmo (ou pior ainda) do que uma implementação de thread único com a API java.io. Além disso, a análise assíncrona com um CompletionHandler é muito mais longa em linhas de código e difícil de implementar corretamente do que uma implementação direta em fluxos antigos.
Agora, as seis implementações seguidas por uma classe contendo todas, mais um método parametrizável main () que permite brincar com o número de arquivos, tamanho e grau de simultaneidade. Observe que o tamanho dos arquivos varia mais menos 20%. Isso evita qualquer efeito, pois todos os arquivos têm exatamente o mesmo tamanho.
rawParse
publicvoid rawParse(finalString targetDir,finalint numberOfFiles)throwsIOException,ParseException{
overrunCount =0;finalint dl =(int)';';StringBuffer lineBuffer =newStringBuffer(1024);for(int f=0; f<numberOfFiles; f++){File fl =newFile(targetDir+filenamePreffix+String.valueOf(f)+".txt");FileInputStream fin =newFileInputStream(fl);BufferedInputStream bin =newBufferedInputStream(fin);int character;while((character=bin.read())!=-1){if(character==dl){// Here is where something is done with each line
doSomethingWithRawLine(lineBuffer.toString());
lineBuffer.setLength(0);}else{
lineBuffer.append((char) character);}}
bin.close();
fin.close();}}publicfinalvoid doSomethingWithRawLine(String line)throwsParseException{// What to do for each lineint fieldNumber =0;finalint len = line.length();StringBuffer fieldBuffer =newStringBuffer(256);for(int charPos=0; charPos<len; charPos++){char c = line.charAt(charPos);if(c==DL0){String fieldValue = fieldBuffer.toString();if(fieldValue.length()>0){switch(fieldNumber){case0:Date dt = fmt.parse(fieldValue);
fieldNumber++;break;case1:double d =Double.parseDouble(fieldValue);
fieldNumber++;break;case2:int t =Integer.parseInt(fieldValue);
fieldNumber++;break;case3:if(fieldValue.equals("overrun"))
overrunCount++;break;}}
fieldBuffer.setLength(0);}else{
fieldBuffer.append(c);}}}
lineReaderParse
publicvoid lineReaderParse(finalString targetDir,finalint numberOfFiles)throwsIOException,ParseException{String line;for(int f=0; f<numberOfFiles; f++){File fl =newFile(targetDir+filenamePreffix+String.valueOf(f)+".txt");FileReader frd =newFileReader(fl);BufferedReader brd =newBufferedReader(frd);while((line=brd.readLine())!=null)
doSomethingWithLine(line);
brd.close();
frd.close();}}publicfinalvoid doSomethingWithLine(String line)throwsParseException{// Example of what to do for each lineString[] fields = line.split(";");Date dt = fmt.parse(fields[0]);double d =Double.parseDouble(fields[1]);int t =Integer.parseInt(fields[2]);if(fields[3].equals("overrun"))
overrunCount++;}
publicvoid nioFilesParse(finalString targetDir,finalint numberOfFiles)throwsIOException,ParseException{for(int f=0; f<numberOfFiles; f++){Path ph =Paths.get(targetDir+filenamePreffix+String.valueOf(f)+".txt");Consumer<String> action =newLineConsumer();Stream<String> lines =Files.lines(ph);
lines.forEach(action);
lines.close();}}classLineConsumerimplementsConsumer<String>{@Overridepublicvoid accept(String line){// What to do for each lineString[] fields = line.split(DL);if(fields.length>1){try{Date dt = fmt.parse(fields[0]);}catch(ParseException e){}double d =Double.parseDouble(fields[1]);int t =Integer.parseInt(fields[2]);if(fields[3].equals("overrun"))
overrunCount++;}}}
nioAsyncParse
publicvoid nioAsyncParse(finalString targetDir,finalint numberOfFiles,finalint numberOfThreads,finalint bufferSize)throwsIOException,ParseException,InterruptedException{ScheduledThreadPoolExecutor pool =newScheduledThreadPoolExecutor(numberOfThreads);ConcurrentLinkedQueue<ByteBuffer> byteBuffers =newConcurrentLinkedQueue<ByteBuffer>();for(int b=0; b<numberOfThreads; b++)
byteBuffers.add(ByteBuffer.allocate(bufferSize));for(int f=0; f<numberOfFiles; f++){
consumerThreads.acquire();String fileName = targetDir+filenamePreffix+String.valueOf(f)+".txt";AsynchronousFileChannel channel =AsynchronousFileChannel.open(Paths.get(fileName),EnumSet.of(StandardOpenOption.READ), pool);BufferConsumer consumer =newBufferConsumer(byteBuffers, fileName, bufferSize);
channel.read(consumer.buffer(),0l, channel, consumer);}
consumerThreads.acquire(numberOfThreads);}classBufferConsumerimplementsCompletionHandler<Integer,AsynchronousFileChannel>{privateConcurrentLinkedQueue<ByteBuffer> buffers;privateByteBuffer bytes;privateString file;privateStringBuffer chars;privateint limit;privatelong position;privateDateFormat frmt =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");publicBufferConsumer(ConcurrentLinkedQueue<ByteBuffer> byteBuffers,String fileName,int bufferSize){
buffers = byteBuffers;
bytes = buffers.poll();if(bytes==null)
bytes =ByteBuffer.allocate(bufferSize);
file = fileName;
chars =newStringBuffer(bufferSize);
frmt =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");
limit = bufferSize;
position =0l;}publicByteBuffer buffer(){return bytes;}@Overridepublicsynchronizedvoid completed(Integer result,AsynchronousFileChannel channel){if(result!=-1){
bytes.flip();finalint len = bytes.limit();int i =0;try{for(i =0; i < len; i++){byte by = bytes.get();if(by=='\n'){// ***// The code used to process the line goes here
chars.setLength(0);}else{
chars.append((char) by);}}}catch(Exception x){System.out.println("Caught exception "+ x.getClass().getName()+" "+ x.getMessage()+" i="+String.valueOf(i)+", limit="+String.valueOf(len)+", position="+String.valueOf(position));}if(len==limit){
bytes.clear();
position += len;
channel.read(bytes, position, channel,this);}else{try{
channel.close();}catch(IOException e){}
consumerThreads.release();
bytes.clear();
buffers.add(bytes);}}else{try{
channel.close();}catch(IOException e){}
consumerThreads.release();
bytes.clear();
buffers.add(bytes);}}@Overridepublicvoid failed(Throwable e,AsynchronousFileChannel channel){}};
O que você quer fazer com o texto? O arquivo é pequeno o suficiente para caber na memória? Eu tentaria encontrar a maneira mais simples de lidar com o arquivo para suas necessidades. A biblioteca FileUtils é muito adequada para isso.
@ PeterLawrey provavelmente significa org.apache.commons.io.FileUtils. O link do Google pode alterar o conteúdo ao longo do tempo, à medida que o significado mais difundido muda, mas isso corresponde à sua consulta e parece correto.
Palec 15/02/2015
2
Infelizmente, hoje em dia não existe readLines(String)e readLines(File)é preterido em favor de readLines(File, Charset). A codificação pode ser fornecida também como uma sequência.
Documentei 15 maneiras de ler um arquivo em Java e testei sua velocidade com vários tamanhos de arquivo - de 1 KB a 1 GB e aqui estão as três principais maneiras de fazer isso:
import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;BufferedReader br;try{
br =newBufferedReader(newFileReader("/fileToRead.txt"));try{String x;while((x = br.readLine())!=null){// Printing out each line in the fileSystem.out.println(x);}}catch(IOException e){
e.printStackTrace();}}catch(FileNotFoundException e){System.out.println(e);
e.printStackTrace();}
Isso é basicamente o mesmo que a resposta de Jesus Ramos, exceto com File em vez de FileReader mais iteração para percorrer o conteúdo do arquivo.
Scanner in =newScanner(newFile("filename.txt"));while(in.hasNext()){// Iterates each line in the fileString line = in.nextLine();// Do something with line}
in.close();// Don't forget to close resource leaks
Arquivo x FileReader: com um FileReader, o arquivo deve existir e as permissões do sistema operacional devem permitir o acesso. Com um arquivo, é possível testar essas permissões ou verificar se o arquivo é um diretório. O arquivo possui funções úteis: isFile (), isDirectory (), listFiles (), canExecute (), canRead (), canWrite (), existe (), mkdir (), delete (). File.createTempFile () grava no diretório temporário padrão do sistema. Este método retornará um objeto de arquivo que pode ser usado para abrir objetos FileOutputStream, etc. source
ThisClark
7
As classes de fluxo em buffer têm muito mais desempenho na prática, tanto que a API NIO.2 inclui métodos que retornam especificamente essas classes de fluxo, em parte para encorajá-lo a sempre usar fluxos em buffer em seu aplicativo.
Aqui está um exemplo:
Path path =Paths.get("/myfolder/myfile.ext");try(BufferedReader reader =Files.newBufferedReader(path)){// Read from the streamString currentLine =null;while((currentLine = reader.readLine())!=null)//do your code here}catch(IOException e){// Handle file I/O exception...}
É verdade que: if(scanner.hasNext()) content = scanner.next();
David Soroko 13/08/2015
1
Isso falha para mim no Android 4.4. Apenas 1024 bytes são lidos. YMMV.
Roger Keays
3
Ainda não o vejo mencionado nas outras respostas até agora. Mas se "Melhor" significa velocidade, o novo Java I / O (NIO) pode fornecer o desempenho mais rápido, mas nem sempre o mais fácil de descobrir para quem está aprendendo.
Esta pode não ser a resposta exata para a pergunta. É apenas outra maneira de ler um arquivo em que você não especifica explicitamente o caminho para o seu arquivo no código Java e, em vez disso, lê-o como um argumento da linha de comandos.
Eu acho que o readAllBytes é mais rápido e mais preciso, porque não substitui a nova linha \ne também pode ser a nova linha \r\n. Depende das suas necessidades, qual delas é adequada.
try{File f =newFile("filename.txt");Scanner r =newScanner(f);while(r.hasNextLine()){String data = r.nextLine();JOptionPane.showMessageDialog(data);}
r.close();}catch(FileNotFoundException ex){JOptionPane.showMessageDialog("Error occurred");
ex.printStackTrace();}
Muito mais rápido, duvido, se você usar uma concatenação simples de seqüências de caracteres em vez de um StringBuilder ...
#
6
Penso que o principal ganho de velocidade é a leitura em blocos de 1 MB (1024 * 1024). No entanto, você pode fazer o mesmo simplesmente passando 1024 * 1024 como segundo argumento para o construtor BufferedReader.
Gb96
3
Eu não acredito que isso seja testado. o uso +=dessa maneira fornece complexidade quadrática (!) para uma tarefa que deve ser complexidade linear. isso começará a rastrear arquivos com mais de alguns mb. Para contornar isso, você deve manter os blocos de texto em uma lista <string> ou usar o construtor de string mencionado acima.
kritzikratzi
5
Muito mais rápido que o que? Certamente não é mais rápido do que anexar a um StringBuffer. -1
Marquês de Lorne
1
@ gb96 Pensei o mesmo sobre tamanhos de buffer, mas o experimento detalhado nesta pergunta deu resultados surpreendentes em um contexto semelhante: um buffer de 16 KB era consistentemente e visivelmente mais rápido.
chiastic-security 12/09/14
-3
String fileName ='yourFileFullNameWithPath';File file =newFile(fileName);// Creates a new file object for your fileFileReader fr =newFileReader(file);// Creates a Reader that you can use to read the contents of a file read your fileBufferedReader br =newBufferedReader(fr);//Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.
O conjunto de linhas acima pode ser escrito em uma única linha como:
Adicionando ao construtor de strings (se o seu arquivo for enorme, é recomendável usar o construtor de strings, caso contrário, use o objeto String normal)
try{StringBuilder sb =newStringBuilder();String line = br.readLine();while(line !=null){
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();}String everything = sb.toString();}finally{
br.close();}
Respostas:
ASCII é um arquivo de texto que você usaria
Readers
para ler. Java também suporta a leitura de um arquivo binário usandoInputStreams
. Se os arquivos que estão sendo lidos forem grandes, você poderá usar umBufferedReader
em cima de umFileReader
para melhorar o desempenho da leitura.Leia este artigo sobre como usar um
Reader
Também recomendo que você baixe e leia este livro maravilhoso (ainda gratuito) chamado Thinking In Java
No Java 7 :
(docs) ou
(docs)
No Java 8 :
(docs)
fonte
Files.lines(…).forEach(…)
não preserva a ordem das linhas, mas é executado em paralelo, @Dash. Se o pedido for importante, você pode usá-loFiles.lines(…).forEachOrdered(…)
, o que deve preservar o pedido (embora não tenha sido verificado).Files.lines(...).forEach(...)
é executado em paralelo? Eu pensei que este era apenas o caso quando você explicitamente faz o fluxo paralelo usandoFiles.lines(...).parallel().forEach(...)
.forEach
não garante nenhuma ordem e o motivo é a fácil paralelização. Se a ordem deve ser preservada, useforEachOrdered
.Minha maneira favorita de ler um arquivo pequeno é usar um BufferedReader e um StringBuilder. É muito simples e direto ao ponto (embora não seja particularmente eficaz, mas bom o suficiente para a maioria dos casos):
Alguns salientaram que após o Java 7 você deve usar os recursos try-with-resources (isto é, fechamento automático):
Quando leio seqüências de caracteres como essa, geralmente quero manipular algumas linhas por linha de qualquer maneira, então vou para essa implementação.
Embora, se eu realmente queira apenas ler um arquivo em uma String, sempre usei o Apache Commons IO com o método da classe IOUtils.toString (). Você pode dar uma olhada na fonte aqui:
http://www.docjar.com/html/api/org/apache/commons/io/IOUtils.java.html
E ainda mais simples com o Java 7:
fonte
code
while (linha! = nula) {sb.append (linha); line = br.readLine (); // Adicione apenas uma nova linha quando a linha de curvatura NÃO for a última linha. If (line! = Null) {sb.append ("\ n"); }}code
A maneira mais fácil é usar a
Scanner
classe em Java e o objeto FileReader. Exemplo simples:Scanner
possui vários métodos para leitura de strings, números, etc ... Você pode procurar mais informações sobre isso na página de documentação do Java.Por exemplo, lendo todo o conteúdo em
String
:Além disso, se você precisar de uma codificação específica, poderá usar isso em vez de
FileReader
:fonte
BufferedReader
while ((line = br.readLine()) != null) { sb.append(line); }
?Aqui está uma solução simples:
fonte
Aqui está outra maneira de fazer isso sem usar bibliotecas externas:
fonte
Eu tive que avaliar as diferentes maneiras. Vou comentar minhas descobertas, mas, em resumo, a maneira mais rápida é usar um BufferedInputStream antigo simples sobre um FileInputStream. Se muitos arquivos precisarem ser lidos, três threads reduzirão o tempo total de execução para aproximadamente a metade, mas a adição de mais threads diminuirá progressivamente o desempenho até que demore três vezes mais para concluir com vinte threads do que com apenas um thread.
A suposição é que você deve ler um arquivo e fazer algo significativo com seu conteúdo. Nos exemplos a seguir, está lendo linhas de um log e conte as que contêm valores que excedem um determinado limite. Portanto, estou assumindo que o Java 8 de
Files.lines(Paths.get("/path/to/file.txt")).map(line -> line.split(";"))
uma linha não é uma opção.Testei em Java 1.8, Windows 7 e unidades SSD e HDD.
Eu escrevi seis implementações diferentes:
rawParse : use BufferedInputStream sobre um FileInputStream e, em seguida, corte linhas lendo byte a byte. Isso superou qualquer outra abordagem de thread único, mas pode ser muito inconveniente para arquivos não ASCII.
lineReaderParse : use um BufferedReader sobre um FileReader, leia linha por linha, divida as linhas chamando String.split (). Isso é aproximadamente 20% mais lento que rawParse.
lineReaderParseParallel : É o mesmo que lineReaderParse, mas usa vários threads. Essa é a opção mais rápida em todos os casos.
nioFilesParse : use java.nio.files.Files.lines ()
nioAsyncParse : use um AsynchronousFileChannel com um manipulador de conclusão e um conjunto de encadeamentos.
nioMemoryMappedParse : use um arquivo mapeado na memória. Essa é realmente uma péssima idéia, gerando tempos de execução pelo menos três vezes maiores do que qualquer outra implementação.
Estes são os tempos médios para a leitura de 204 arquivos de 4 MB cada, em uma unidade i7 e SSD de quatro núcleos. Os arquivos são gerados em tempo real para evitar o cache do disco.
Encontrei uma diferença menor do que eu esperava entre a execução em um SSD ou uma unidade de disco rígido, sendo o SSD aproximadamente 15% mais rápido. Isso pode ocorrer porque os arquivos são gerados em um disco rígido não fragmentado e são lidos sequencialmente; portanto, a unidade rotativa pode funcionar quase como um SSD.
Fiquei surpreso com o baixo desempenho da implementação nioAsyncParse. Eu implementei algo da maneira errada ou a implementação de vários threads usando o NIO e um manipulador de conclusão executa o mesmo (ou pior ainda) do que uma implementação de thread único com a API java.io. Além disso, a análise assíncrona com um CompletionHandler é muito mais longa em linhas de código e difícil de implementar corretamente do que uma implementação direta em fluxos antigos.
Agora, as seis implementações seguidas por uma classe contendo todas, mais um método parametrizável main () que permite brincar com o número de arquivos, tamanho e grau de simultaneidade. Observe que o tamanho dos arquivos varia mais menos 20%. Isso evita qualquer efeito, pois todos os arquivos têm exatamente o mesmo tamanho.
rawParse
lineReaderParse
lineReaderParseParallel
nioFilesParse
nioAsyncParse
IMPLEMENTAÇÃO RUNNABLE COMPLETA DE TODOS OS CASOS
https://github.com/sergiomt/javaiobenchmark/blob/master/FileReadBenchmark.java
fonte
Aqui estão os três métodos de trabalho e testados:
Usando
BufferedReader
Usando
Scanner
Usando
FileReader
Leia o arquivo inteiro sem um loop usando a
Scanner
classefonte
java.nio.file.Files
? Podemos agora usar apenasreadAllLines
,readAllBytes
elines
.Os métodos
org.apache.commons.io.FileUtils
também podem ser muito úteis, por exemplo:fonte
O que você quer fazer com o texto? O arquivo é pequeno o suficiente para caber na memória? Eu tentaria encontrar a maneira mais simples de lidar com o arquivo para suas necessidades. A biblioteca FileUtils é muito adequada para isso.
fonte
org.apache.commons.io.FileUtils
. O link do Google pode alterar o conteúdo ao longo do tempo, à medida que o significado mais difundido muda, mas isso corresponde à sua consulta e parece correto.readLines(String)
ereadLines(File)
é preterido em favor dereadLines(File, Charset)
. A codificação pode ser fornecida também como uma sequência.Documentei 15 maneiras de ler um arquivo em Java e testei sua velocidade com vários tamanhos de arquivo - de 1 KB a 1 GB e aqui estão as três principais maneiras de fazer isso:
java.nio.file.Files.readAllBytes()
Testado para funcionar em Java 7, 8 e 9.
java.io.BufferedReader.readLine()
Testado para funcionar em Java 7, 8, 9.
java.nio.file.Files.lines()
Isso foi testado para funcionar no Java 8 e 9, mas não funcionará no Java 7 devido ao requisito de expressão lambda.
fonte
Abaixo está um exemplo de como fazê-lo da maneira Java 8. Supondo que o
text.txt
arquivo esteja na raiz do diretório do projeto do Eclipse.fonte
Usando BufferedReader:
fonte
Isso é basicamente o mesmo que a resposta de Jesus Ramos, exceto com File em vez de FileReader mais iteração para percorrer o conteúdo do arquivo.
... joga
FileNotFoundException
fonte
As classes de fluxo em buffer têm muito mais desempenho na prática, tanto que a API NIO.2 inclui métodos que retornam especificamente essas classes de fluxo, em parte para encorajá-lo a sempre usar fluxos em buffer em seu aplicativo.
Aqui está um exemplo:
Você pode substituir este código
com
Eu recomendo este artigo para aprender os principais usos do Java NIO e IO.
fonte
Provavelmente não tão rápido quanto na E / S em buffer, mas bastante conciso:
O
\Z
padrão informaScanner
que o delimitador é EOF.fonte
if(scanner.hasNext()) content = scanner.next();
Ainda não o vejo mencionado nas outras respostas até agora. Mas se "Melhor" significa velocidade, o novo Java I / O (NIO) pode fornecer o desempenho mais rápido, mas nem sempre o mais fácil de descobrir para quem está aprendendo.
http://download.oracle.com/javase/tutorial/essential/io/file.html
fonte
A maneira mais simples de ler dados de um arquivo em Java é usar a classe File para ler o arquivo e a classe Scanner para ler o conteúdo do arquivo.
PS: Não esqueça de importar java.util. *; para o Scanner funcionar.
fonte
O Goiaba fornece uma linha para isso:
fonte
Esta pode não ser a resposta exata para a pergunta. É apenas outra maneira de ler um arquivo em que você não especifica explicitamente o caminho para o seu arquivo no código Java e, em vez disso, lê-o como um argumento da linha de comandos.
Com o seguinte código,
vá em frente e execute-o com:
Isso leria o conteúdo
input.txt
e o imprimiria no seu console.Você também pode
System.out.println()
gravar em um arquivo específico através da linha de comando da seguinte maneira:Isso iria ler
input.txt
e escrever paraoutput.txt
.fonte
Você pode usar readAllLines e o
join
método para obter todo o conteúdo do arquivo em uma linha:Ele usa a codificação UTF-8 por padrão, que lê os dados ASCII corretamente.
Além disso, você pode usar o readAllBytes:
Eu acho que o readAllBytes é mais rápido e mais preciso, porque não substitui a nova linha
\n
e também pode ser a nova linha\r\n
. Depende das suas necessidades, qual delas é adequada.fonte
Para aplicativos da Web Maven baseados em JSF, basta usar o ClassLoader e a
Resources
pasta para ler qualquer arquivo que você desejar:Coloque a dependência do Apache Commons IO em seu POM:
Use o código abaixo para lê-lo (por exemplo, abaixo está lendo em um arquivo .json):
Você pode fazer o mesmo com arquivos de texto, arquivos .properties, esquemas XSD , etc.
fonte
Os Cactoos oferecem uma única linha declarativa:
fonte
Use Java kiss se isso for sobre simplicidade de estrutura:
fonte
Basta usar o java 8 Stream.
fonte
fonte
O método mais intuitivo é introduzido no Java 11
Files.readString
PHP tem esse luxo de décadas atrás! ☺
fonte
Este código que eu programei é muito mais rápido para arquivos muito grandes:
fonte
+=
dessa maneira fornece complexidade quadrática (!) para uma tarefa que deve ser complexidade linear. isso começará a rastrear arquivos com mais de alguns mb. Para contornar isso, você deve manter os blocos de texto em uma lista <string> ou usar o construtor de string mencionado acima.O conjunto de linhas acima pode ser escrito em uma única linha como:
Adicionando ao construtor de strings (se o seu arquivo for enorme, é recomendável usar o construtor de strings, caso contrário, use o objeto String normal)
fonte