Eu recebi uma lista de alunos em um arquivo CSV e preciso cadastrá-los no meu sistema:

 Alex Felipe;21 
 Cléber Nascimento;16 
 Felipe de Souza;25 
 João da Silva;18 
 Juliana Guimarães;18 
 Maria Cristina;23 
 Pâmela Aguiar;17

public class Aluno {

    private final String nome; 
    private final int idade;

    public Aluno(String nome, int idade) {
        this.nome = nome; 
        this.idade = idade; 
    }
}
Banner da promoção da black friday, com os dizeres: A Black Friday Alura está chegando. Faça parte da Lista VIP, receba o maior desconto do ano em primeira mão e garanta bônus exclusivos. Quero ser VIP

Preciso digitar as informações deles no meu sistema. Usarei a classe Scanner do pacote java.util para receber os dados do teclado:


Scanner sc = new Scanner(System.in);

System.out.println("Digite o nome do aluno:"); 
String nome = sc.nextLine(); 
System.out.println("Informe a idade do aluno:"); 
int idade = sc.nextInt();

System.out.println("aluno: " + nome + "\\nidade: " + idade);

Pegando o primeiro resultado:

 Digite o nome do aluno: Alex Felipe 
 Informe a data de nascimento do aluno: 21 
 aluno: Alex Felipe 
 idade: 21

O método nextLine() permite a leitura de String e o método nextInt() permite a leitura de int. Enviando os dados para o aluno:


Aluno aluno = new Aluno(nome, idade);

System.out.println(aluno);

Verificando a impressão:

 nome: Alex Felipe idade: 21

Ótimo, consegui cadastrar um aluno! Agora vamos cadastrar o restante dos alunos:

 Digite o nome do aluno: Cleber Nascimento Informe a idade do aluno: 16 nome: Cleber Nascimento idade: 16 Digite o nome do aluno: Felipe de Souza Informe a idade do aluno: 25 nome: Felipe de Souza idade: 25 Digite o nome do aluno: João da Silva Informe a idade do aluno: 18 nome: João da Silva idade: 18

...

Espera aí! Isso já está ficando cansativo! Será que eu vou ter que cadastrar todos esses alunos na unha? Se apenas com 7 está sendo esse sofrimento imagine com mais 30! Vai tirar a paciência de qualquer um!

Além de permitir a leitura de dados por meio do teclado, a classe Scanner possibilita a leitura de arquivos! Basta informar no construtor que ao invés de ler pelo teclado(System.in), queremos ler um arquivo específico instanciando a classe File do pacote java.io:


Scanner sc = new Scanner(new File("usuarios.csv"));

Pronto! Agora precisaremos ler linha por linha fazendo iterações com um while por meio do método hasNext() que informa se ainda existe linhas para ler:


while (sc.hasNext()) { 
    //O while só para quando não tiver mais linhas para ler 
}

Para pegar o próximo elemento do arquivo usamos o método next():


while (sc.hasNext()) {

    String elemento = sc.next(); 
    System.out.println(elemento);

}

Se testarmos nosso código:

 Alex Felipe;21 
 Cleber Nascimento;16 
 Felipe de Souza;25 ...

Ops! Dessa maneira eu não vou conseguir separar os dados do aluno... Além de fazer a leitura do arquivo, o Scanner tem o método useDelimiter() que delimita a leitura do elemento, ou seja, determina até que ponto precisa pegar o elemento, por exemplo, eu quero que ele pegue o elemento até aparecer um ";":


Scanner sc = new Scanner(new File("arquivo.csv"))
    .useDelimiter(";");

Executando o código mais uma vez:

 Alex Felipe 21 
 Cleber Nascimento 16 
 Felipe de Souza 25

...

Ótimo! Separei as informações, agora irei instanciar os meus alunos:


String nome = sc.next(); 
int idade = Integer.parseInt(sc.next());

Aluno aluno = new Aluno(nome, idade); 
System.out.println(aluno);

Testando o nosso código:

 Exception in thread "main" 
 java.lang.NumberFormatException: For input string: "21 Cleber Nascimento"

Que estranho... Problema na conversão? Que String grotesca é essa? Parecia que as informações de nome e idade estavam separadas corretamente... O que aconteceu nesse caso é que o nosso delimitador está separando as informações até o momento em que ele acha um ";" entre a idade e o próximo nome do aluno não existe um ";" tem apenas uma quebra de linha, ou seja, precisamos informar ao Scanner que ao mesmo tempo que delimitamos pelo ";" queremos que ele delimita por quebra de linha também:


Scanner sc = new Scanner(new File("arquivo.csv")).useDelimiter(";|\\\\n");

O pipe(|) indica que queremos que delimite por ";" ou "\n" que significa quebra de linha. Testando novamente:

 Exception in thread "main" 
 java.lang.NumberFormatException: For input string: "21 "

Outra Exception? Que doideira! Como podemos ver ele já separou a idade do nome do outro aluno, porém ele ainda deixou uma quebra de linha e por isso não foi possível fazer a conversão para int. Nesse caso podemos usar o método trim() da própria classe String que ajusta o conteúdo contido na String eliminando quebras de linhas ou espaços em branco:


String nome = sc.next(); 
int idade = Integer.parseInt(sc.next().trim());

Aluno aluno = new Aluno(nome, idade);

System.out.println(aluno);

Conferindo o resultado:

 nome: Alex Felipe idade: 21 
 nome: Cleber Nascimento idade: 
 16 nome: Felipe de Souza idade: 25

...

Excelente! Agora o meu sistema é capaz de ler o arquivo CSV e cadastrar os alunos pra mim!

Vimos que para receber dados de meios externos em java nós podemos utilizar a classe Scanner que tem a capacidade de receber dados por meio do teclado ou arquivos, porém nem sempre quando lemos as informações de um arquivo o resultado é esperado, então precisamos sempre verificar as seguintes informações:

  • Se existir algum carácter que separa cada elemento use um delimitador
  • Se for necessário utilizar mais de um delimitador utilize o pipe (|)
  • Se sempre estiver pegando o próximo elemento ao invés da linha inteira, sempre use o delimitador '\n'

Gostou da classe Scanner? Quer conhecer outras alternativas para a classe Scanner e outras bibliotecas da linguagem Java? Conheça a Formação Java.

Alex Felipe
Alex Felipe

Alex é instrutor e desenvolvedor e possui experiência em Java, Kotlin, Android. Atualmente cria conteúdo no canal https://www.youtube.com/@AlexFelipeDev.

Veja outros artigos sobre Programação