Lendo e Manipulando arquivos CSV com Java

Olá hoje veremos como realizar a leitura e manipulação de arquivos CSV com Java, mostrando que as novas versões da plataforma Java deixaram algumas tarefas simples de serem realizadas.


Exemplo de Arquivo

Hoje em dia é comum ao realizar integrações ou carga de dados o uso de arquivos CSV, isto porque, este arquivo possui uma estrutura de fácil entendimento e simples de manipular na maioria das plataformas de desenvolvimento.

Para realizar a leitura dos dados vamos manipular um arquivo com as seguintes colunas: namecpfagephone address:

name;cpf;age;phone;address
caio;123456789;20;1145223643;Avenida Paulista
vinicius;147852369;18;1125253625;Avenida Manoel
sandra;963258741;30;1174587858;Rua Teixeira
regina;125478522;40;1145254536;Rua Fernando 
fernando;785245563;42;1145253669;Rua Pereira
augusto;456123014;50;1125363633;Avenida Paulinia
maria;456123789;10;1125455525;Avenida Nossa Senhora

Para representar os dados em objetos Java iremos utilizar a seguinte classe:

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

@Getter
@ToString
@AllArgsConstructor
public class User {
 
 private String name, cpf;
 private Integer age;
 private String phone, address;
}

Realizando a Leitura do Arquivo

Para entender o processo de leitura do arquivo, vamos começar apenas exibindo os dados existentes, neste tutorial iremos utilizar a classes Files, que faz parte da NIO API da plataforma Java:

Files.lines(Paths.get("file.csv"))
     .forEach(System.out::println);

O Resultado desse trecho de código será o abaixo:

name;cpf;age;phone;address
caio;123456789;20;1145223643;Avenida Paulista
vinicius;147852369;18;1125253625;Avenida Manoel
sandra;963258741;30;1174587858;Rua Teixeira
regina;125478522;40;1145254536;Rua Fernando 
fernando;785245563;42;1145253669;Rua Pereira
augusto;456123014;50;1125363633;Avenida Paulinia
maria;456123789;10;1125455525;Avenida Nossa Senhora

Perceba que para lermos o conteúdo do arquivo o processo é muito simples, apenas utilizamos o método Files.lines, passando como argumento o Path do arquivo, após este processo podemos manipular o Stream<String> da forma que nosso programa necessita.

O Segundo passo da leitura será a remoção do cabeçalho do arquivo, isto porque, na maioria das importações oque realmente importa são os valores, vamos analisar como ficará o código:


Files.lines(Paths.get("file.csv"))
     .skip(1)
     .forEach(System.out::println);

Aqui foi adicionado ao pipeline a operação skip(1), que faz o primeiro item do Stream ser removido, sendo a linha contendo as informações de cabeçalho do arquivo:

caio;123456789;20;1145223643;Avenida Paulista
vinicius;147852369;18;1125253625;Avenida Manoel
sandra;963258741;30;1174587858;Rua Teixeira
regina;125478522;40;1145254536;Rua Fernando 
fernando;785245563;42;1145253669;Rua Pereira
augusto;456123014;50;1125363633;Avenida Paulinia
maria;456123789;10;1125455525;Avenida Nossa Senhora

Realizando conversões e lógicas com Stream API

Agora vamos adicionar a leitura do arquivo algumas operações mais complexas, a primeira será a conversão da linha em um Objeto do tipo User:


1
2
3
4
5
Files.lines(Paths.get("file.csv"))
     .skip(1)
     .map(line -> line.split(";"))
     .map(col-> new User(col[0], col[1], Integer.parseInt(col[2]), col[3], col[4]))
     .forEach(System.out::println);

Aqui utilizamos da operação map() da Stream API, que é utilizada para realizar transformações de dados, na linha 3 é realizado a transformação da linha do arquivo em um Array de colunas, isto utilizando o método split(";"), onde o ; é o caractere utilizado como quebra, já na linha 4, passamos os dados do String[] para o construtor da classe User, o resultado será o abaixo:


User(name=caio, cpf=123456789, age=20, phone=1145223643, address=Avenida Paulista)
User(name=vinicius, cpf=147852369, age=18, phone=1125253625, address=Avenida Manoel)
User(name=sandra, cpf=963258741, age=30, phone=1174587858, address=Rua Teixeira)
User(name=regina, cpf=125478522, age=40, phone=1145254536, address=Rua Fernando )
User(name=fernando, cpf=785245563, age=42, phone=1145253669, address=Rua Pereira)
User(name=augusto, cpf=456123014, age=50, phone=1125363633, address=Avenida Paulinia)
User(name=maria, cpf=456123789, age=10, phone=1125455525, address=Avenida Nossa Senhora)

Agora vamos utilizar a Stream API para aplicar alumas lógicas, vamos exibir todos os usuários que tenham mais que 30 anos:

1
2
3
4
5
6
Files.lines(Paths.get("file.csv"))
     .skip(1)
     .map(list -> list.split(";"))
     .map(str -> new User(str[0], str[1], Integer.parseInt(str[2]), str[3], str[4]))
     .filter(usr -> usr.getAge() > 30)
     .forEach(System.out::println);

Aqui utilizamos o operação de filter, onde na linha 5, passamos como parâmetro uma expressão lambda com a regra para exibir apenas objetos User que tenham o getAge() > 30, o resultado será o abaixo:

User(name=regina, cpf=125478522, age=40, phone=1145254536, address=Rua Fernando )
User(name=fernando, cpf=785245563, age=42, phone=1145253669, address=Rua Pereira)
User(name=augusto, cpf=456123014, age=50, phone=1125363633, address=Avenida Paulinia)

Após estes exemplos podemos notar como é simples a leitura de arquivos CSV com Java, vale ressaltar que existem várias outras maneiras e formas de realizar esta leitura, sendo que devemos analisar qual a melhor forma dependendo do tamanho do arquivo, e lógicas que queremos aplicar nos resultados.

Até a próxima.

Código fonte

Referências

Comentários

  1. muito bom. parabens.

    Posso usar a mesma logica para arquivos grandes com mais de 300mb por exemplo?

    ResponderExcluir
    Respostas
    1. Blz Cleriston,

      Então sim você pode usar esta estratégia, principalmente a parte onde usamos Stream e Lambdas para executar o pipeline sobre o arquivo, mas também é interessante analisar outras formas de leitura que talvez sejam mais performáticas que a API NIO para leitura de grandes arquivos, para teste neste mesmo git repository do tutorial, tem um projeto chamado read-files-performance, lá fiz um comparativo de performance no processo de leitura de arquivos com outras APIs.

      Abraços.

      Excluir

Postar um comentário

Popular Posts

Criando arquivos de log com Log4J

Monitorando o Tomcat com Java VisualVM

Injeção de dependências em Java EE usando @Inject, @EJB e @Resource ?

Gerenciamento de Transações com EJB - Parte 2

AngularJS - Formatando Datas com o Filter Date

JBoss AS 7 - Instalação e Configuração

Configurando o arquivo application.properties do SpringBoot

Métodos Utilitários da Classe String

Criando Módulos e DataSources no Wildfly

Criando uma Aplicação com Spring Boot e MongoDB