Importação de Arquivos Grandes entre Aplicações

Olá amigos.

Sou programador Java Jr e estou me deparando com o seguinte problema:
Minha empresa está desenvolvendo uma aplicação que utiliza dados importados de outro sistema de informação. Por uma questão de segurança os dados são gravados em um arquivo .txt que é lido através da API ?java.io?.

O grande problema é que o tal arquivo.txt é exageradamente grande. Mais de um milhão de registros em um só arquivo com mais de trinta megabytes . Em uma simulação foi calculado um total de nove horas para que a aplicação conseguisse importar todos os registros.

Devido a minha falta de experiência não sei o que pode ser feito para reduzir o prazo de execução da tarefa. Pode ser a forma como eu estou persistindo os dados no banco ou a API de leitura do arquivo .txt, ou até mesmo a lógica utilizada.

Por favor me digam como eu poderia fazer isso de uma forma mais eficiente.

[code]
/**

  • Classe que executa a aplicação
    */
    package teste;

import dao.ClienteDao;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class TesteInsereRegistros {

public static void main(String[] args) throws FileNotFoundException, IOException, Exception {

    Cliente cliente = new Cliente();
    ClienteDao clienteDao = new ClienteDao();

    /**
     * Representa o caminho original do arquivo
     */
    String caminhoArquivos = System.getProperty("user.dir") + "\\utils\\utils\\";
    FileReader reader = new FileReader(new File(caminhoArquivos + "Cadastro_de_Cliente.txt"));
    BufferedReader leitor = new BufferedReader(reader);
    String linha = null;

    int totalLetrasLinha;
    int contador = 0;
    while ((linha = leitor.readLine()) != null) {

        linha = leitor.readLine();
        totalLetrasLinha = linha.length();
        cliente.setCodigo(linha.substring(0, 7).trim());
        cliente.setCpf(linha.substring(7, 18).trim());
        cliente.setNome(linha.substring(18, totalLetrasLinha).trim());
        clienteDao.setCliente(cliente);

        System.out.println(contador);
        contador++;
    }

}

}[/code]

[code]/**

  • Classe que acessa o banco de dados
    */

package dao;
import com.mysql.jdbc.Connection;
import teste.Cliente;

public class ClienteDao {

public void setCliente(Cliente cliente) throws Exception {

    Connection conexao = (Connection) Conexao.conectar();
    java.sql.PreparedStatement stm = conexao.prepareStatement("INSERT INTO cliente (`codigo`, `cpf`,`nome`) values(?,?,?);");

    stm.setString(1, cliente.getCodigo());
    stm.setString(2, cliente.getCpf());
    stm.setString(3, cliente.getNome());

    stm.execute();

    stm.close();
    //conexao.close();

}

}[/code]

[quote=berinjelablues]Olá amigos.
Por favor me digam como eu poderia fazer isso de uma forma mais eficiente.
[/quote]

Utilize NIO para ler este seu arquivo grande. http://java.sun.com/javase/6/docs/api/java/nio/package-summary.html . O ganho com a utilização do java.nio é muito significativo.

Para inserir no banco, utilize algum mecanismo de Bulk Insert, ou seja, insira registros de 1000 em 1000 por exemplo.

Você pode usar thread para a operação salvar em paralelo.

Pode gerenciar melhor a conexão com o banco também. (usando apache DBCP por exemplo).

Isto pode te ajudar

http://www.precisejava.com/javaperf/j2ee/JDBC.htm

Tem também o comentado bulk insert do amigo acima.

É uma ótima opção

Outro detalhe que talvez valha a pena analisar, todos os registros são unicos? ou podem ser duplicados?

quando NIO, é bem mais rapido que IO :slight_smile:

Respondendo ao companheiro ‘Felagund’; nenhum registro é duplicado.

Agradeço a ajuda e atenção de todos e prometo postar a solução logo que eu a encontre.

Se nenhum registro é duplicado, vc pode fazer da seguinte maneira, primeiro ler o arquivo da base e armazenar um em

List<Cliente> clientes = new ArrayList<Cliente>();

no caso ao invez de fazer um clienteDao.setCliente vc adiciona a lista.

No final da leitura do arquivo, vc percorre a lista e vai inserindo os registros.

Salve o preparedStatement, use o clearParameters para que dessa forma vc não tenha que preparar o statement a cada iteração. Será bem mais rápido.