Estou usando o idioma abaixo há algum tempo. E parece ser o mais difundido, pelo menos nos sites que visitei.
Existe uma maneira melhor / diferente de ler um arquivo em uma string em Java?
private String readFile(String file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader (file));
String line = null;
StringBuilder stringBuilder = new StringBuilder();
String ls = System.getProperty("line.separator");
try {
while((line = reader.readLine()) != null) {
stringBuilder.append(line);
stringBuilder.append(ls);
}
return stringBuilder.toString();
} finally {
reader.close();
}
}
byte[] Files.readAllBytes(file);
Para aqueles que sugerem a solução de scanner de uma linha: Você não precisa fechá-la?Respostas:
Leia todo o texto de um arquivo
O Java 11 adicionou o método readString () para ler arquivos pequenos como um
String
, preservando os terminadores de linha:Para versões entre Java 7 e 11, aqui está um idioma compacto e robusto, agrupado em um método utilitário:
Ler linhas de texto de um arquivo
O Java 7 adicionou um método de conveniência para ler um arquivo como linhas de texto, representadas como a
List<String>
. Essa abordagem é "com perda" porque os separadores de linha são removidos do final de cada linha.O Java 8 adicionou o
Files.lines()
método para produzir aStream<String>
. Novamente, esse método está com perdas porque os separadores de linha são removidos. Se umIOException
for encontrado durante a leitura do arquivo, ele será agrupado em umUncheckedIOException
, jáStream
que não aceita lambdas que geram exceções verificadas.Isso
Stream
precisa de umaclose()
ligação; isso está mal documentado na API e suspeito que muitas pessoas nem percebem queStream
tem umclose()
método. Certifique-se de usar um bloco ARM, como mostrado.Se você estiver trabalhando com uma fonte que não seja um arquivo, poderá usar o
lines()
método emBufferedReader
vez disso.Utilização de memória
O primeiro método, que preserva as quebras de linha, pode exigir temporariamente memória várias vezes o tamanho do arquivo, porque por um curto período de tempo o conteúdo do arquivo bruto (uma matriz de bytes) e os caracteres decodificados (cada um com 16 bits, mesmo que codificado) 8 bits no arquivo) residem na memória de uma só vez. É mais seguro aplicar a arquivos que você sabe serem pequenos em relação à memória disponível.
O segundo método, linhas de leitura, geralmente é mais eficiente em memória, porque o buffer de bytes de entrada para decodificação não precisa conter o arquivo inteiro. No entanto, ainda não é adequado para arquivos muito grandes em relação à memória disponível.
Para ler arquivos grandes, você precisa de um design diferente para o seu programa, que leia um pedaço de texto de um fluxo, o processe e depois passe para o próximo, reutilizando o mesmo bloco de memória de tamanho fixo. Aqui, "grande" depende das especificações do computador. Atualmente, esse limite pode ser de muitos gigabytes de RAM. O terceiro método, usando a,
Stream<String>
é uma maneira de fazer isso, se os "registros" de entrada forem linhas individuais. (Usar oreadLine()
método deBufferedReader
é o equivalente processual a essa abordagem.)Codificação de caracteres
Uma coisa que está faltando na amostra na postagem original é a codificação de caracteres. Existem alguns casos especiais em que o padrão da plataforma é o que você deseja, mas eles são raros e você deve justificar sua escolha.
A
StandardCharsets
classe define algumas constantes para as codificações necessárias para todos os tempos de execução do Java:O padrão da plataforma está disponível na
Charset
própria classe :Nota: Esta resposta substitui amplamente minha versão do Java 6. O utilitário do Java 7 simplifica com segurança o código, e a resposta antiga, que usava um buffer de bytes mapeados, impedia que o arquivo lido fosse excluído até que o buffer mapeado fosse coletado de lixo. Você pode visualizar a versão antiga através do link "editado" nesta resposta.
fonte
FileChannel#map
, em geral, é inutilizável.Se você deseja usar uma biblioteca externa, consulte o Apache Commons IO (200KB JAR). Ele contém um
org.apache.commons.io.FileUtils.readFileToString()
método que permite ler um inteiroFile
em umString
com uma linha de código.Exemplo:
fonte
Uma solução muito enxuta baseada em
Scanner
:Ou, se você deseja definir o conjunto de caracteres:
Ou, com um bloco try-with-resources , que chamará
scanner.close()
você:Lembre-se de que o
Scanner
construtor pode lançar umIOException
. E não se esqueça de importarjava.io
ejava.util
.Fonte: Blog de Pat Niemeyer
fonte
java.util.NoSuchElementException
.desde o java 7, você pode fazer dessa maneira.
fonte
Se você estiver procurando por uma alternativa que não envolva uma biblioteca de terceiros (por exemplo, Commons I / O ), use a classe Scanner :
fonte
Scanner scanner = new Scanner((Readable) new BufferedReader(new FileReader(file)));
. Caso contrário, você poderá capturar apenas parte do arquivo.A goiaba tem um método semelhante ao do Commons IOUtils que Willi aus Rohr mencionou:
EDIT by PiggyPiglet
Files#toString
está obsoleto e com a remoção do Octobor 2019. Em vez disso, useFiles.asCharSource(new File(path), StandardCharsets.UTF_8).read();
EDIT por Oscar Reyes
Este é o código subjacente (simplificado) da biblioteca citada:
Editar (por Jonik): O texto acima não corresponde ao código fonte das versões recentes do Guava. Para a fonte atual, consulte as classes Arquivos , CharStreams , ByteSource e CharSource no pacote com.google.common.io .
fonte
Closer
no CharSource . O código na resposta não é a fonte atual atual da Goiaba........
fonte
new String(Files.readAllBytes(FileSystems.getDefault().getPath( filename)));
new String(Files.readAllBytes(Paths.get(filename)));
:-)Paths
é aparentemente 1,7+ como estáFileSystems
. (Dang it!)Se você precisar de um processamento de sequência (processamento paralelo), o Java 8 possui a excelente API de Stream.
Mais exemplos estão disponíveis nas amostras JDK
sample/lambda/BulkDataOperations
que podem ser baixadas da página de download do Oracle Java SE 8Outro exemplo de um liner
fonte
Esse código normalizará as quebras de linha, que podem ou não ser o que você realmente deseja fazer.
Aqui está uma alternativa que não faz isso e que é (IMO) mais simples de entender do que o código NIO (embora ainda use
java.nio.charset.Charset
):fonte
Reuniu todas as maneiras possíveis para ler o arquivo como sequência do disco ou da rede.
Goiaba: Google usando classes
Resources
,Files
APACHE - COMMO IO usando as classes IOUtils, FileUtils
Java 8 BufferReader usando API de Stream
Classe de scanner com regex
\A
. que corresponde ao início da entrada.Java 7 (
java.nio.file.Files.readAllBytes
)BufferedReader
usandoInputStreamReader
.Exemplo com o método principal para acessar os métodos acima.
@Vejo
fonte
Se é um arquivo de texto, por que não usar o apache commons-io ?
Tem o seguinte método
Se você quiser as linhas como uma lista, use
fonte
Desde o JDK 11:
fonte
Para ler um arquivo como binário e converter no final
fonte
Com o Java 7, esta é minha opção preferida para ler um arquivo UTF-8:
Desde o Java 7, o JDK possui a nova
java.nio.file
API, que fornece muitos atalhos, portanto nem sempre são necessárias bibliotecas de terceiros para operações simples de arquivo.fonte
O Java tenta ser extremamente geral e flexível em tudo o que faz. Como resultado, algo que é relativamente simples em uma linguagem de script (seu código seria substituído por "
open(file).read()
" em python) é muito mais complicado. Parece não haver uma maneira mais curta de fazer isso, exceto usando uma biblioteca externa (como Willi aus Rohr mencionou). Suas opções:Sua melhor aposta é provavelmente a segunda, pois possui menos dependências.
fonte
byte[] bytes = Files.readAllBytes(someFile.toPath());
Usando o JDK 8 ou superior:
nenhuma biblioteca externa usada
Você pode criar um novo objeto String a partir do conteúdo do arquivo (Usando classes do
java.nio.file
pacote):fonte
Há uma variação no mesmo tema que usa um loop for, em vez de um while, para limitar o escopo da variável de linha. Se é "melhor" é uma questão de gosto pessoal.
fonte
line
variável. A edição declarou duas vezes, o que seria um erro de compilação.Se você não tiver acesso à
Files
classe, poderá usar uma solução nativa.fonte
Uma solução flexível usando IOUtils do Apache commons-io em combinação com o StringWriter :
Funciona com qualquer leitor ou fluxo de entrada (não apenas com arquivos), por exemplo, ao ler de um URL.
fonte
Esteja ciente de que o uso
fileInputStream.available()
do número inteiro retornado não precisa representar o tamanho real do arquivo, mas a quantidade de bytes estimada que o sistema deve poder ler do fluxo sem bloquear as E / S. Uma maneira simples e segura pode ser assimDeve-se considerar que essa abordagem não é adequada para codificações de caracteres de vários bytes, como UTF-8.
fonte
available()
método, não há garantia de que o final do arquivo seja atingido no caso de o método retornar 0. Nesse caso, você pode acabar com um arquivo incompleto. O que é pior, o número de bytes realmente lidos pode ser menor que o valor retornadoavailable()
, nesse caso, você obtém saída corrompida.Este usa o método
RandomAccessFile.readFully
, parece estar disponível no JDK 1.0!fonte
Você pode experimentar a classe Scanner e File, algumas soluções de linhas
fonte
Usuário
java.nio.Files
para ler todas as linhas de arquivo.fonte
fonte
cannot find symbol
.Ainda não posso comentar outras entradas, então deixarei aqui.
Uma das melhores respostas aqui ( https://stackoverflow.com/a/326448/1521167 ):
ainda tem uma falha. Ele sempre coloca o novo caractere de linha no final da string, o que pode causar alguns erros estranhos. Minha sugestão é alterá-lo para:
fonte
Após Ctrl + F'ing após o Scanner, acho que a solução do Scanner também deve ser listada. Da maneira mais fácil de ler, fica assim:
Se você usa o Java 7 ou mais recente (e realmente deveria) considere usar o try-with-resources para facilitar a leitura do código. Não há mais coisas pontilhadas espalhando tudo. Mas isso é principalmente uma escolha estilística.
Estou postando isso principalmente por completismo, pois se você precisar fazer muito isso, deve haver coisas em java.nio.file.Files que devem fazer o trabalho melhor.
Minha sugestão seria usar Files # readAllBytes (Path) para pegar todos os bytes e alimentá-lo com a nova String (byte [] Charset) para obter uma String em que você possa confiar. Charsets será mau para você durante a sua vida, então cuidado com isso agora.
Outros deram código e outras coisas, e eu não quero roubar sua glória. ;)
fonte
Usando esta biblioteca , é uma linha:
fonte
Além disso, se o seu arquivo estiver dentro de um jar, você também poderá usar este:
O caminho deve começar,
/
por exemplo, se o seu jar forEntão você deseja invocá-lo assim:
fonte
Em uma linha (Java 8), supondo que você tenha um Reader:
fonte
Com base na resposta de @ erickson, você pode usar:
fonte