Como ler um arquivo em Java

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.

Read more

Java - Gravar no arquivo

As várias maneiras de gravar dados no arquivo usando Java.

Read more

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.