Lendo um Arquivo CSV

JavaBeginner
Pratique Agora

Introdução

Neste laboratório, aprenderemos como ler arquivos CSV (Comma-Separated Values) em Java. CSV é um formato de arquivo comum usado para armazenar dados tabulares, como planilhas ou exportações de banco de dados. Cada linha em um arquivo CSV representa uma linha de dados, com colunas separadas por vírgulas.

Exploraremos três abordagens diferentes para ler arquivos CSV em Java:

  • Usando a classe BufferedReader do pacote java.io
  • Usando a classe Scanner do pacote java.util
  • Usando a biblioteca OpenCSV, uma biblioteca de terceiros popular para processamento de CSV

Ao final deste laboratório, você será capaz de escolher o método mais apropriado para ler arquivos CSV em suas aplicações Java, com base em seus requisitos específicos.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível avançado com uma taxa de conclusão de 36%. Recebeu uma taxa de avaliações positivas de 100% dos estudantes.

Criar um Arquivo CSV de Exemplo e a Estrutura do Projeto

Antes de começarmos a ler arquivos CSV, vamos garantir que nosso projeto esteja configurado corretamente. Nesta etapa, examinaremos a estrutura do nosso arquivo CSV e criaremos nossa classe Java principal.

Entendendo Arquivos CSV

Um arquivo CSV (Comma-Separated Values) armazena dados tabulares em texto simples. Cada linha representa uma linha, e as colunas são separadas por vírgulas. Arquivos CSV são amplamente utilizados para troca de dados devido à sua simplicidade e compatibilidade com muitas aplicações como Excel, Google Sheets e sistemas de banco de dados.

Examinando Nosso Arquivo CSV de Exemplo

Nosso ambiente de laboratório já inclui um arquivo CSV de exemplo em ~/project/sample.csv. Vamos primeiro dar uma olhada em seu conteúdo:

cat ~/project/sample.csv

Você deve ver a seguinte saída:

name,age,city
John,25,New York
Alice,30,Los Angeles
Bob,28,Chicago
Eve,22,Boston

Este arquivo CSV contém quatro linhas de dados (incluindo a linha de cabeçalho) com informações sobre pessoas, suas idades e cidades.

Criando Nossa Classe Java

Agora, vamos criar uma nova classe Java chamada CSVReaderDemo.java no diretório src que usaremos ao longo deste laboratório.

No VSCode, clique no ícone Explorer na barra lateral, navegue até o diretório ~/project/src, clique com o botão direito nele e selecione "New File". Nomeie o arquivo CSVReaderDemo.java.

Adicione a seguinte estrutura básica ao arquivo:

public class CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("CSV Reader Demo");

        // We will add CSV reading code here in the next steps
    }
}
Create Java File

Vamos compilar e executar nossa classe Java para verificar se tudo está configurado corretamente:

cd ~/project
javac -d . src/CSVReaderDemo.java
java CSVReaderDemo

Você deve ver a saída:

CSV Reader Demo

Ótimo! Agora temos nossa estrutura de projeto pronta. Nas próximas etapas, implementaremos diferentes métodos para ler nosso arquivo CSV.

Lendo Arquivos CSV Usando BufferedReader

Nesta etapa, implementaremos nossa primeira abordagem para ler arquivos CSV usando a classe BufferedReader do pacote java.io. Este é um método comum e direto para ler arquivos de texto em Java.

Entendendo BufferedReader

BufferedReader é uma classe que lê texto de um fluxo de entrada de caracteres, armazenando caracteres em buffer para fornecer uma leitura eficiente de caracteres, arrays e linhas. O tamanho do buffer pode ser especificado ou o tamanho padrão pode ser usado.

Implementando a Leitura de CSV com BufferedReader

Vamos atualizar nosso arquivo CSVReaderDemo.java para ler o arquivo CSV usando BufferedReader. Substitua todo o conteúdo do arquivo pelo seguinte código:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("Reading CSV using BufferedReader");

        // Path to our CSV file
        String csvFile = "sample.csv";

        // Lists to store our data
        List<List<String>> data = new ArrayList<>();

        // Try-with-resources to ensure the reader gets closed automatically
        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
            String line;

            // Read each line from the file
            while ((line = br.readLine()) != null) {
                // Split the line by comma and convert to a List
                String[] values = line.split(",");
                List<String> lineData = Arrays.asList(values);

                // Add the line data to our main list
                data.add(lineData);
            }

            // Print the data we read
            System.out.println("\nData read from CSV file:");
            for (int i = 0; i < data.size(); i++) {
                List<String> row = data.get(i);
                System.out.println("Row " + i + ": " + String.join(", ", row));
            }

        } catch (IOException e) {
            System.err.println("Error reading the CSV file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
Update Java File

Vamos compilar e executar nosso código atualizado:

cd ~/project
javac -d . src/CSVReaderDemo.java
java CSVReaderDemo

Você deve ver uma saída semelhante a esta:

Reading CSV using BufferedReader

Data read from CSV file:
Row 0: name, age, city
Row 1: John, 25, New York
Row 2: Alice, 30, Los Angeles
Row 3: Bob, 28, Chicago
Row 4: Eve, 22, Boston

Explicação do Código

  1. Importamos as classes Java necessárias para operações de I/O de arquivos e estruturas de dados.
  2. Definimos o caminho para o nosso arquivo CSV (sample.csv).
  3. Criamos um List<List<String>> para armazenar nossos dados CSV como uma lista bidimensional.
  4. Usamos um bloco try-with-resources para fechar automaticamente o BufferedReader após o uso.
  5. Lemos cada linha do arquivo com br.readLine().
  6. Para cada linha, dividimos por vírgulas usando line.split(",") e convertemos para um List.
  7. Adicionamos cada linha à nossa lista principal de dados.
  8. Finalmente, imprimimos os dados para verificar se lemos corretamente.

A abordagem BufferedReader é simples e eficiente para ler arquivos de texto, incluindo arquivos CSV. No entanto, ela tem limitações ao lidar com formatação CSV mais complexa, como campos contendo vírgulas ou quebras de linha entre aspas.

Na próxima etapa, exploraremos outra abordagem usando a classe Scanner.

Lendo Arquivos CSV Usando Scanner

Nesta etapa, implementaremos nossa segunda abordagem para ler arquivos CSV usando a classe Scanner do pacote java.util. A classe Scanner fornece uma maneira conveniente de ler entrada formatada de várias fontes.

Entendendo Scanner

A classe Scanner divide sua entrada em tokens usando um padrão delimitador, que por padrão corresponde a espaços em branco. Os tokens resultantes podem então ser convertidos em valores de diferentes tipos usando os vários métodos next.

Implementando a Leitura de CSV com Scanner

Vamos atualizar nosso arquivo CSVReaderDemo.java para ler o arquivo CSV usando Scanner. Substitua todo o conteúdo do arquivo pelo seguinte código:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("Reading CSV using Scanner");

        // Path to our CSV file
        String csvFile = "sample.csv";

        // Lists to store our data
        List<List<String>> data = new ArrayList<>();

        try (Scanner scanner = new Scanner(new File(csvFile))) {
            // Read each line from the file
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();

                // Split the line by comma and convert to a List
                String[] values = line.split(",");
                List<String> lineData = Arrays.asList(values);

                // Add the line data to our main list
                data.add(lineData);
            }

            // Print the data we read
            System.out.println("\nData read from CSV file:");
            for (int i = 0; i < data.size(); i++) {
                List<String> row = data.get(i);
                System.out.println("Row " + i + ": " + String.join(", ", row));
            }

        } catch (FileNotFoundException e) {
            System.err.println("CSV file not found: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Vamos compilar e executar nosso código atualizado:

cd ~/project
javac -d . src/CSVReaderDemo.java
java CSVReaderDemo

Você deve ver uma saída semelhante a esta:

Reading CSV using Scanner

Data read from CSV file:
Row 0: name, age, city
Row 1: John, 25, New York
Row 2: Alice, 30, Los Angeles
Row 3: Bob, 28, Chicago
Row 4: Eve, 22, Boston

Explicação do Código

  1. Importamos as classes Java necessárias para operações de arquivo, Scanner e estruturas de dados.
  2. Definimos o caminho para o nosso arquivo CSV (sample.csv).
  3. Criamos um List<List<String>> para armazenar nossos dados CSV como uma lista bidimensional.
  4. Usamos um bloco try-with-resources para fechar automaticamente o Scanner após o uso.
  5. Lemos cada linha do arquivo com scanner.nextLine() desde que scanner.hasNextLine() retorne true.
  6. Para cada linha, dividimos por vírgulas usando line.split(",") e convertemos para um List.
  7. Adicionamos cada linha à nossa lista principal de dados.
  8. Finalmente, imprimimos os dados para verificar se lemos corretamente.

A abordagem Scanner é semelhante à abordagem BufferedReader, mas fornece métodos mais convenientes para analisar diferentes tipos de dados. No entanto, como o BufferedReader, ela tem limitações ao lidar com formatação CSV complexa.

Na próxima etapa, exploraremos uma abordagem mais robusta usando a biblioteca OpenCSV, que lida com a formatação CSV complexa de forma mais eficaz.

Lendo Arquivos CSV Usando a Biblioteca OpenCSV

Nesta etapa, implementaremos nossa terceira abordagem para ler arquivos CSV usando a biblioteca OpenCSV. OpenCSV é uma biblioteca de terceiros que fornece recursos robustos de análise de CSV, lidando com cenários complexos como campos contendo vírgulas ou quebras de linha entre aspas.

Entendendo OpenCSV

OpenCSV é uma biblioteca de análise de CSV para Java que suporta todas as variações básicas do formato CSV. Ao contrário das abordagens anteriores, OpenCSV lida corretamente com campos entre aspas contendo vírgulas, quebras de linha e outros caracteres especiais que, de outra forma, interromperiam a divisão simples por vírgulas.

Configurando OpenCSV

Primeiro, vamos baixar a biblioteca OpenCSV e suas dependências:

cd ~/project
mkdir -p lib
curl -L -o lib/opencsv-5.7.1.jar https://repo1.maven.org/maven2/com/opencsv/opencsv/5.7.1/opencsv-5.7.1.jar
curl -L -o lib/commons-lang3-3.12.0.jar https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar
curl -L -o lib/commons-text-1.10.0.jar https://repo1.maven.org/maven2/org/apache/commons/commons-text/1.10.0/commons-text-1.10.0.jar
curl -L -o lib/commons-beanutils-1.9.4.jar https://repo1.maven.org/maven2/commons-beanutils/commons-beanutils/1.9.4/commons-beanutils/1.9.4.jar
curl -L -o lib/commons-collections-3.2.2.jar https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar
curl -L -o lib/commons-logging-1.2.jar https://repo1.maven.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.jar

Criando um Arquivo CSV Mais Complexo

Vamos criar um arquivo CSV mais complexo que inclua campos entre aspas com vírgulas:

echo 'name,description,price
"Laptop","High-performance laptop, with SSD",999.99
"Smartphone","Latest model, with dual camera",499.99
"Headphones","Noise-canceling, wireless",149.99' > ~/project/products.csv

Implementando a Leitura de CSV com OpenCSV

Agora, vamos atualizar nosso arquivo CSVReaderDemo.java para ler o arquivo CSV usando OpenCSV. Substitua todo o conteúdo do arquivo pelo seguinte código:

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvValidationException;
import java.io.FileReader;
import java.io.IOException;

public class CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("Reading CSV using OpenCSV");

        // Path to our CSV file with complex data
        String csvFile = "products.csv";

        try (CSVReader reader = new CSVReader(new FileReader(csvFile))) {
            // Read and print the header
            String[] header = reader.readNext();
            if (header != null) {
                System.out.println("\nHeader: " + String.join(", ", header));
            }

            // Read and print each line
            String[] nextLine;
            int rowNumber = 1;

            System.out.println("\nData read from CSV file:");
            while ((nextLine = reader.readNext()) != null) {
                System.out.println("Row " + rowNumber + ":");
                for (int i = 0; i < nextLine.length; i++) {
                    System.out.println("  " + header[i] + ": " + nextLine[i]);
                }
                rowNumber++;
                System.out.println();
            }

        } catch (IOException | CsvValidationException e) {
            System.err.println("Error reading the CSV file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Vamos compilar e executar nosso código atualizado:

cd ~/project
javac -cp ".:lib/*" -d . src/CSVReaderDemo.java
java -cp ".:lib/*" CSVReaderDemo

Você deve ver uma saída semelhante a esta:

Reading CSV using OpenCSV

Header: name, description, price

Data read from CSV file:
Row 1:
  name: Laptop
  description: High-performance laptop, with SSD
  price: 999.99

Row 2:
  name: Smartphone
  description: Latest model, with dual camera
  price: 499.99

Row 3:
  name: Headphones
  description: Noise-canceling, wireless
  price: 149.99

Explicação do Código

  1. Importamos as classes necessárias da biblioteca OpenCSV e Java I/O.
  2. Definimos o caminho para o nosso arquivo CSV (products.csv).
  3. Criamos um objeto CSVReader para ler o arquivo CSV.
  4. Lemos a linha do cabeçalho com reader.readNext() e a armazenamos para uso posterior.
  5. Em seguida, lemos cada linha subsequente com reader.readNext() em um loop até que não haja mais linhas.
  6. Para cada linha, imprimimos cada campo junto com seu cabeçalho correspondente.

A biblioteca OpenCSV lida com a formatação CSV complexa automaticamente, analisando corretamente os campos com vírgulas entre aspas. Isso o torna ideal para arquivos CSV do mundo real que podem conter dados complexos.

Vantagens do OpenCSV

OpenCSV oferece várias vantagens em relação às abordagens básicas:

  1. Ele lida corretamente com campos entre aspas contendo vírgulas, quebras de linha e outros caracteres especiais.
  2. Ele fornece suporte integrado para leitura em beans (objetos Java).
  3. Ele suporta recursos avançados como separadores personalizados, caracteres de aspas e caracteres de escape.
  4. Ele lida com arquivos CSV grandes de forma eficiente.

Para a maioria das aplicações do mundo real que lidam com arquivos CSV, usar uma biblioteca dedicada como OpenCSV é a abordagem recomendada.

Resumo

Neste laboratório, exploramos três abordagens diferentes para ler arquivos CSV em Java:

  1. Usando BufferedReader: Uma abordagem simples usando a biblioteca padrão Java I/O. Funciona bem para arquivos CSV básicos, mas tem limitações ao lidar com formatação CSV complexa.
  2. Usando Scanner: Outra abordagem usando a biblioteca utilitária padrão Java. Como BufferedReader, é adequado para arquivos CSV simples, mas não possui suporte para formatação CSV complexa.
  3. Usando OpenCSV: Uma abordagem robusta usando uma biblioteca de terceiros especificamente projetada para processamento de CSV. Ele lida com formatação CSV complexa, incluindo campos entre aspas contendo vírgulas, quebras de linha e outros caracteres especiais.

Cada abordagem tem seus pontos fortes e casos de uso:

  • BufferedReader e Scanner são boas opções para arquivos CSV simples quando você deseja evitar dependências externas.
  • OpenCSV é a melhor opção para aplicações do mundo real que lidam com arquivos CSV potencialmente complexos.

Ao entender essas diferentes abordagens, você pode escolher o método mais apropriado com base em seus requisitos específicos e na complexidade de seus dados CSV.

Arquivos CSV são amplamente utilizados em processamento de dados, troca de dados e cenários de integração de dados. A capacidade de ler e processar arquivos CSV é uma habilidade valiosa para desenvolvedores Java, particularmente em aplicações focadas em dados e integrações com outros sistemas.