Leitura de arquivo com scanner

Olá Pessoal boa tarde, adoraria saber se alguém pode me ajudar com esse código abaixo, na minha aplicação o usuário com frequência irá subir alguns arquivos e eles tem duas informações, numero e nome separados por -> ;
porem no arquivo eu simulo alguns possíveis problemas como números sem nome e meu código não se comporta bem contra esses possíveis problemas.

Outro detalhe é que meu SOUT esta duplicando e eu não sei porque.

Se alguém puder me ajudar, agradeço.

    public void adicionaArquivo(MultipartFile file) throws IOException {

    InputStream inputStream = file.getInputStream();
    List<ContatoDTO> contato = new ArrayList<>();

    //cria um scanner para ler o arquivo
    Scanner leitor = new Scanner(inputStream);
    //variavel que armazenara as linhas do arquivo
    String linhasDoArquivo = new String();

    //percorre todo o arquivo
    while (leitor.hasNext()) {

        try {
            //recebe cada linha do arquivo
            linhasDoArquivo = leitor.nextLine();

            //separa os campos entre as virgulas de cada linha
            String[] valoresEntreVirgulas = linhasDoArquivo.split(";");

            for (int i = 0; i < valoresEntreVirgulas.length; i++) {
                ContatoDTO c = new ContatoDTO();
                c.setTelefone(valoresEntreVirgulas[0]);
                c.setNome(valoresEntreVirgulas[1]);
                contato.add(c);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    for (int i = 0; i < contato.size(); i++) {
        System.out.println("telefone : " + contato.get(i).getTelefone());
        System.out.println("Nome : " + contato.get(i).getNome());
    }
    System.out.println("qt de linhas : " + contato.size());
}

meu arquivo

71999998811;nome1
71999998812;nome2
71999998813;nome3
71999998814;nome4
71999998815;nome5
71999998816;nome6
71999998817;nome7
71999998818;nome8
71999998819;nome9
71999998810;nome10

71999998810;nome11
71999998810
71999998810;
71999998810;nome14
71999998855;nome15

meu log

O problema é que quando vc faz o split, vc sempre espera que seja retornado um array com 2 elementos: um número e um nome.

Só que no arquivo que está lendo existem linhas que ou estão em branco, ou só tem o número seguido por ponto e virgula sem nome, ou nem ponto e virgula tem.

Nestes casos o split vai retornar um array vazio ou um array com apenas um elemento. Por isso o ArrayIndexOutOfBoundsException.

Sobre a duplicação na saída, é por causa daquele loop dentro do adicionaArquivo.

Corrija-o deixando assim:

// for (int i = 0; i < valoresEntreVirgulas.length; i++) {
    ContatoDTO c = new ContatoDTO();
    c.setTelefone(valoresEntreVirgulas[0]);
    c.setNome(valoresEntreVirgulas[1]);
    contato.add(c);
// }

Não precisa instanciar essa variável aqui.

Se recebe uma linha de cada vez, chame a variável de linha e não de linhas.

Se essa variável armazena os campos, o nome dela deveria ser campos.

Você não precisa do for, como nosso amigo @wldomiciano já explicou.

Entretanto você precisa testar se realmente recebeu 2 campos e se o conteúdo deles é válido.

Refiz aqui, agora passou certinho sem dar erro e se comportando bem com relação a tudo, isso é oque acho.
muito obrigado ai pessoal

se quiserem adicionar algo, sou todo ouvidos :slight_smile:

public void adicionaArquivo(GrupoDTO grupo, MultipartFile file) throws IOException {
    
    Validadores validadores = new Validadores();
    InputStream inputStream = file.getInputStream();
    List<ContatoDTO> contato = new ArrayList<>();

    //cria um scanner para ler o arquivo
    Scanner leitor = new Scanner(inputStream);
    //variavel que armazenara as linhas do arquivo
    String linhaDoArquivo;

    //percorre todo o arquivo
    while (leitor.hasNext()) {
        
        try {
            //recebe cada linha do arquivo
            linhaDoArquivo = leitor.nextLine();

            //separa os campos entre as virgulas de cada linha
            String[] campos = linhaDoArquivo.split(";");
            
            try {
                
                if (!"".equals(linhaDoArquivo)) {
                    if (campos.length == 2) {
                        
                        ContatoDTO c = new ContatoDTO();
                        c.setConta(grupo.getConta());
                        c.setGrupo(grupo.getId());
                        c.setTelefone(validadores.validadorTelefone(campos[0]));
                        c.setNome(campos[1]);
                        contato.add(c);
                        
                    } else if (campos.length == 1) {
                        
                        if (validadores.validadorTelefone(campos[0]) != null) {
                            ContatoDTO c = new ContatoDTO();
                            c.setConta(grupo.getConta());
                            c.setGrupo(grupo.getId());
                            c.setTelefone(validadores.validadorTelefone(campos[0]));
                            contato.add(c);
                        }
                        
                    } else if (campos.length == 0 || campos.length > 2) {
                        
                    }
                } else {
                    
                }
                
            } catch (NullPointerException e) {
                System.out.println("null pointer aqui!");
                e.printStackTrace();
            } catch (StringIndexOutOfBoundsException e) {
                System.out.println("vazou o array!");
                e.printStackTrace();
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    for (int i = 0; i < contato.size(); i++) {
        System.out.println("linha");
        System.out.println("telefone : " + contato.get(i).getTelefone());
        System.out.println("Nome : " + contato.get(i).getNome());
    }
    System.out.println("qt de linhas : " + contato.size());
}
1 curtida