Como ler um arquivo em Java
1. Introdução
Neste artigo, veremos como podemos ler um arquivo de um caminho de classe, URL ou dentro de um arquivo JAR, usando classes Java padrão.
Leitura adicional:
Java - Criar um arquivo
Como criar um arquivo em Java usando JDK 6, JDK 7 com NIO ou Commons IO.
2. Configuração
Usaremos um conjunto de exemplos de teste usando apenas as classes principais do Java e, nos testes, usaremos asserções usando matchersHamcrest.
Os testes compartilharão um métodoreadFromInputStream comum que transformaInputStream toString para facilitar a afirmação dos resultados:
private String readFromInputStream(InputStream inputStream)
throws IOException {
StringBuilder resultStringBuilder = new StringBuilder();
try (BufferedReader br
= new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = br.readLine()) != null) {
resultStringBuilder.append(line).append("\n");
}
}
return resultStringBuilder.toString();
}
Observe que existem outras maneiras de alcançar o mesmo resultado. Você pode consultarthis article para algumas alternativas.
3. Ler o arquivo do Classpath
Esta seção explica como ler um arquivo disponível em um caminho de classe. Vamos ler o “fileTest.txt” disponível emsrc/main/resources:
@Test
public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
Class clazz = FileOperationsTest.class;
InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
String data = readFromInputStream(inputStream);
Assert.assertThat(data, containsString(expectedData));
}
No trecho de código acima, usamos a classe atual para carregar um arquivo usandogetResourceAsStream method e passamos o caminho absoluto do arquivo a ser carregado.
O mesmo método está disponível em uma posiçãoClassLoader também:
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
String data = readFromInputStream(inputStream);
Obtemos oclassLoader da classe atual usandogetClass().getClassLoader().
A principal diferença é que ao usar a posiçãogetResourceAsStream on aClassLoader instance, o caminho é tratado como absoluto a partir da raiz do caminho de classe.
Quando usado em relação a umaClass instance, , o caminho pode ser relativo ao pacote ou um caminho absoluto, que é sugerido pela barra inicial.
Of course, note that in practice, open streams should always be closed, comoInputStream em nosso exemplo:
InputStream inputStream = null;
try {
File file = new File(classLoader.getResource("fileTest.txt").getFile());
inputStream = new FileInputStream(file);
//...
}
finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. Ler arquivo com JDK7
No JDK7, o pacote NIO foi atualizado significativamente. Vejamos um exemplo usando a classeFilese o métodoreadAllBytes. O métodoreadAllBytes aceita uma classePath. Path e pode ser considerado uma atualização dejava.io.File com algumas operações adicionais implementadas:
@Test
public void givenFilePath_whenUsingFilesReadAllBytes_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
Path path = Paths.get(getClass().getClassLoader()
.getResource("fileTest.txt").toURI());
byte[] fileBytes = Files.readAllBytes(path);
String data = new String(fileBytes);
Assert.assertEquals(expectedData, data.trim());
}
Este método também oferece uma maneira conveniente de ler o conteúdo de um arquivo em umString.
5. Ler arquivo com JDK8
O JDK8 oferece o métodolines() dentro da classeFiles. Ele retorna umStream de elementos String.
Vejamos um exemplo de como ler dados em bytes e decodificar usando o conjunto de caracteres UTF-8:
@Test
public void givenFilePath_whenUsingFilesLines_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
Path path = Paths.get(getClass().getClassLoader()
.getResource("fileTest.txt").toURI());
Stream lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();
Assert.assertEquals(expectedData, data.trim());
}
Usando o Stream com canais IO como operações de arquivo, precisamos fechar o stream explicitamente usando o métodoclose().
Como podemos ver, a APIFiles oferece outra maneira fácil de ler o conteúdo do arquivo em umString.
6. Leia o arquivo com FileUtils
Outra opção comum é usar a classeFileUtils do pacotecommons. Precisamos adicionar a seguinte dependência:
commons-io
commons-io
2.5
Certifique-se de verificar a versão de dependência mais recentehere.
O código de leitura do arquivo pode se parecer com:
@Test
public void givenFileName_whenUsingFileUtils_thenFileData() {
String expectedData = "Hello World from fileTest.txt!!!";
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("fileTest.txt").getFile());
String data = FileUtils.readFileToString(file, "UTF-8");
Assert.assertEquals(expectedData, data.trim());
}
Aqui, passamos o objetoFile para o métodoreadFileToString() da classeFileUtils. Esta classe de utilitário consegue carregar o conteúdo sem a necessidade de escrever qualquer código clichê para criar uma instânciaInputStreame ler os dados.
7. Leia o arquivo comIOUtils
Outra opção comum é usar oIOUtils class do pacotecommons. Você precisará adicionar a mesma dependênciacommon-io mencionada no exemploFileUtils anterior.
Vamos dar uma olhada em um exemplo de uso:
@Test
public void givenFileName_whenUsingIOUtils_thenFileData() {
String expectedData = "This is a content of the file";
FileInputStream fis = new FileInputStream("src/test/resources/fileToRead.txt");
String data = IOUtils.toString(fis, "UTF-8");
assertEquals(expectedData, data.trim());
}
Aqui, passamos o objetoFileInputStream para o métodotoString() da classeIOUtils. Esta classe de utilitário consegue carregar o conteúdo sem a necessidade de escrever qualquer código clichê para criar uma instânciaInputStreame ler os dados.
8. Leia o conteúdo do URL
Para ler o conteúdo do URL, usaremos o URL “/” em nosso exemplo como:
@Test
public void givenURLName_whenUsingURL_thenFileData() {
String expectedData = "example";
URL urlObject = new URL("/");
URLConnection urlConnection = urlObject.openConnection();
InputStream inputStream = urlConnection.getInputStream();
String data = readFromInputStream(inputStream);
Assert.assertThat(data, containsString(expectedData));
}
Também existem maneiras alternativas de se conectar a um URL. Aqui usamos as classesURLeURLConnection disponíveis no SDK padrão.
9. Ler arquivo de um JAR
Para ler um arquivo localizado dentro de um arquivo JAR, precisaremos de um JAR com um arquivo dentro dele. Para o nosso exemplo, leremos “LICENSE.txt” do arquivo “hamcrest-library-1.3.jar”:
@Test
public void givenFileName_whenUsingJarFile_thenFileData() {
String expectedData = "BSD License";
Class clazz = Matchers.class;
InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
String data = readFromInputStream(inputStream);
Assert.assertThat(data, containsString(expectedData));
}
Aqui queremos carregarLICENSE.txt que reside na biblioteca Hamcrest, então usaremos a classeMatcher’s que ajuda a obter um recurso. O mesmo arquivo também pode ser carregado usando o carregador de classes.
10. Conclusão
Neste tutorial, vimos como ler um arquivo de vários locais, como classpath, URL ou arquivos jar.
Também vimos várias maneiras de ler o conteúdo de um arquivo
Você pode encontrar o código-fonte nos seguintesGitHub repo.