Erro ao ler um arquivo txt ? =Exception in thread "main" java.lang.OutOfMemoryError: Java heap

19 respostas
snowblacksoul

Bom dia a todos, sei que esse tópico tem no GUJ, mas não específico com o netbeans e o tamanho do arquivo que estou pegando.
Seguinte, preciso subir no banco esse arquivo txt que vai de 150MB a 3Gigas e está dando erro de "java.lang.OutOfMemoryError: Java heap " vou colocar o código para que todos tenham ideia do que estou fazendo e preciso!
Tem alguma solução para pegar arquivos GRANDES, como fazer?!
gratos a todos que puderem colaborar

Aqui o código

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author E449045
 */
public class ImportNrcInfos {

    public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, SQLException, IOException {   
  
       File file = new File("c:/teste/NRC_INFOS_20110801.txt"); // o path do arquivo, ex.: "C:\Importacao.txt"   
       FileReader fileReader = new FileReader(file);   
       BufferedReader bufferedReader = new BufferedReader(fileReader);  
      //  File file = new File(new BufferedReader(new FileReader("c:/teste/NRC_INFOS_20110801.txt")));
                                     
            //sqljdbc/sqljdbc4/jtds-1.2
              Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                Connection connection = DriverManager.getConnection("jdbc:sqlserver://SRV_RG:1433;databaseName=BASES","pa","****");
                System.out.println("conectado");
        
            Statement stmt = (Statement) connection.createStatement();   
  
     		List<Infos> listLivros = new ArrayList<Infos>();   
             while (bufferedReader.ready()) {   
  
            String linha = bufferedReader.readLine(); // lê uma linha...   
            String[] arrayDados = linha.split("\t");  // separa os dados por seu delimitador...   

            Infos livro = new Infos(); 
           livro.setPRODUTO_COMERCIAL(arrayDados[0]);
           livro.setNRC(arrayDados[1]);
           livro.setSISTEMA(arrayDados[2]);
           livro.setSEGMENTO(arrayDados[3]);
           livro.setCLASSE(arrayDados[4]);
           livro.setTERMINAL(arrayDados[5]);
           livro.setLOCALIDADE(arrayDados[6]);
           livro.setCD_CLIENTE(arrayDados[7]);
           livro.setCD_CONTA(arrayDados[8]);
           livro.setCD_PC(arrayDados[9]);
           livro.setTP_PRTE(arrayDados[10]);
           livro.setDT_INI_PRQE(arrayDados[11]);
           livro.setDT_FIM_PRQE(arrayDados[12]);
           livro.setDT_INS_PRQE(arrayDados[13]);
           livro.setDT_RET_PRQE(arrayDados[14]);
           livro.setDH_PRTE(arrayDados[15]);
           livro.setIN_MGRO_ATIS_IN(arrayDados[16]);   
           livro.setIN_MGRO_ATIS_AC(arrayDados[17]);   
           livro.setIN_MGRO_ATIS_FA(arrayDados[18]);   
           livro.setIN_MGRO_ATIS_CO(arrayDados[19]);   
                                 
        listLivros.add(livro);   
        }   
		System.out.println("------------------------------------");   
  
        for (Infos livro : listLivros) {   
  
            String sentenca = "insert into dbo.NRC_INFOS_201108(PRODUTO_COMERCIAL,NRC,SISTEMA,SEGMENTO,CLASSE,TERMINAL,LOCALIDADE,"
                    + "CD_CLIENTE,CD_CONTA,CD_PC,TP_PRTE,DT_INI_PRQE,DT_FIM_PRQE,DT_INS_PRQE,"
                    + "DT_RET_PRQE,DH_PRTE,IN_MGRO_ATIS_IN,IN_MGRO_ATIS_AC,"
                    + "IN_MGRO_ATIS_FA,IN_MGRO_ATIS_CO) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";   
            PreparedStatement statementInsert = connection.prepareStatement(sentenca); 
            
            statementInsert.setString(1, livro.getPRODUTO_COMERCIAL());   
            statementInsert.setString(2, livro.getNRC()); 
            statementInsert.setString(3, livro.getSISTEMA()); 
            statementInsert.setString(4, livro.getSEGMENTO()); 
            statementInsert.setString(5, livro.getCLASSE()); 
            statementInsert.setString(6, livro.getTERMINAL()); 
            statementInsert.setString(7, livro.getLOCALIDADE()); 
            statementInsert.setString(8, livro.getCD_CLIENTE()); 
            statementInsert.setString(9, livro.getCD_CONTA()); 
            statementInsert.setString(10, livro.getCD_PC()); 
            statementInsert.setString(11, livro.getTP_PRTE()); 
            statementInsert.setString(12, livro.getDT_INI_PRQE()); 
            statementInsert.setString(13, livro.getDT_FIM_PRQE()); 
            statementInsert.setString(14, livro.getDT_INS_PRQE()); 
            statementInsert.setString(15, livro.getDT_RET_PRQE()); 
            statementInsert.setString(16, livro.getDH_PRTE()); 
            statementInsert.setString(17, livro.getIN_MGRO_ATIS_IN());          
            statementInsert.setString(18, livro.getIN_MGRO_ATIS_AC());   
            statementInsert.setString(19, livro.getIN_MGRO_ATIS_FA());   
            statementInsert.setString(20, livro.getIN_MGRO_ATIS_CO());   
              
            statementInsert.execute();   
           // statementInsert.executeUpdate();   
            //stmt.executeUpdate(sentenca);   
        }   
        connection.commit();   
        System.out.println(listLivros);   
  
    }   
}

O Erro!

19 Respostas

denisspitfire

Mas oque voce precisa fazer com este arquivo? Exibir? Manipular?

L

Cara, não manjo muito, mas se voce esta tentando fazer isso com arquivos de 150mb pra mais e esta dando erro de memória, tenta executar com um arquivo menor, ou voce pode tentar importar o projeto para o Eclipse e tentar pelo menos ‘abrir’ o arquivo na memoria…

Quem sabe funciona,

Boa sorte :smiley:

nel

Oi!

Tu consegue imaginar jogar 3 GB em um Buffer de memória?
Terás de pensar muito bem na sua manipulação do arquivo, principalmente porque ao que vi existem dois laços de repetição:

1 - Leitura e armazenamento em memório das informações
2 - Inserir no banco

Não acredito que com as configurações default da JVM tu vá conseguir fazer isso meu caro, acredito que terás de aumentar consideravelmente o HEAP da sua JVM e quebrar em pedaços esse arquivo, assim como é feito em um download de arquivo, por exemplo.

snowblacksoul

Eu já imaginei isso!
Sem usar as configurações da JVM, existe um outro meio de fazer isso
sem utilizar a memoria!?

snowblacksoul

os arquivos aqui são relativamente grandes, e não queria mais usar a dts do ruinwindows!!

L

Olha assim se cara acho que não, voce teria que associar um arquivo de swap no HD para so esse processo, o que, SE der certo vai demorar pra fazer todo o processamento…

R

Em vez de acumular todos os livros para inserção posterior, por que não inserir cada livro assim que tiver acabado de lê-lo?

snowblacksoul

como assim roger?

R

Assim:

String linha = bufferedReader.readLine();
while (linha != null) {
  Infos livro = new Infos();
  /* ... PENDENTE: Preencher [livro] a partir de [linha] ... */
  /* ... PENDENTE: Inserir [livro] no Banco de Dados ... */
  linha = bufferedReader.readLine();
}

Você não precisa acumular os livros no ArrayList para gravá-los no BD posteriormente, basta gravar o livro no BD assim que tiver acabado de lê-lo do arquivo de texto.

Danillo_Moreno

Não sou o Roger, mas entendi o que ele quis dizer…

Ao invés de você fazer assim…

while (bufferedReader.ready()) {   
... 
listLivros.add(livro);    //Estou guardando TUDO em memória
}

Viu como você está lendo o txt todinho e “guardando em memória” para depois…

for (Infos livro : listLivros) {   // Estou lendo da memória
...  
}

… ler da memória e gravar no banco…

A minha sugestão é a seguinte:

1 - Leia a linha;

2 - faça os tratamentos necessários;

3 - grave no banco.

e assim sucessivamente até acabar o arquivo.

Espero ter ajudado…

Lindberg

Pessoal não tem memoria que aguente !!!

eu tenho um texto com mais de 120 mil linhas.

o certo ler uma linha e salva no banco …
ler a proxima e salva no banco a te o fim.

como vc ja tem exemplos ai vai mais um … esse forum é D + :lol: :smiley: fala ai … pessoal

o codigo abaixo é para arquivo pequeno !!!

import java.io.*;
import javax.swing.*;

public class lertxttod {

	public String nomArq;

	public lertxttod(String arqv) {
		{
		    nomArq = arqv;
		}			
	}



	public String lerArquivotexto()  {
		String result = "";
	try {

		BufferedReader br = new BufferedReader(new FileReader(nomArq));

		String dados=" ";
		while ((dados = br.readLine()) != null)   // lendo texto
		{ 
//			result = result + dados + "\n";
AQUI SALVA NO BANCO
		} 

		return result;
	}

			catch (IOException ioe) {
				JOptionPane.showMessageDialog(null,
				"Erro de leitura no arquivo " + nomArq + "'",
				"Mensagem",	JOptionPane.PLAIN_MESSAGE );
			result = ""; 
			}

	return result;
	}

}

espero ter contribuido tambem junto com a pessoal acima …

snowblacksoul

entendi Danilo!!!

snowblacksoul

valeu Lindberg
vou testar aqui e respondo depois do almoço galera!!
ta fogo esse post rsrsrs

nel

Oi!

Um artigo interessante para uso: Tuning Java I/O Performance.
Leia, extrai a informação e persista no banco.

snowblacksoul

Mas pera ae pessoal, não seria mais fácil ao invés de criar um txt para subir no banco,pegar as informações direto no banco de dados e importar em outro banco!!
Isso é possível!?

nel

snowblacksoul:
Mas pera ae pessoal, não seria mais fácil ao invés de criar um txt para subir no banco,pegar as informações direto no banco de dados e importar em outro banco!!
Isso é possível!?

Mas calma digo eu…tu quer fazer um Dump, é isso?
Quer migrar informações de um banco de dados para outro e atualmente está usando um arquivo TXT para intermediar isso?

snowblacksoul

Isso mesmo Nel, estou criando um txt de um banco e importando as informações em outro banco!
Pensando, não seria muito mais fácil fazer daquela forma que falei, ao invés de criar o txt!?

nel

snowblacksoul:
Isso mesmo Nel, estou criando um txt de um banco e importando as informações em outro banco!
Pensando, não seria muito mais fácil fazer daquela forma que falei, ao invés de criar o txt!?

Na minha opinião, sem dúvidas.
Pode ir na base de dados e carregar o ResultSet de 100 em 100 registros e ir gravando aos poucos no outro banco.
Muio provávél que tu não tenha mais o problema de Heap.

snowblacksoul

Não não sei implementar dessa forma, como ficaria isso?! esse resultset?!

Criado 18 de agosto de 2011
Ultima resposta 18 de ago. de 2011
Respostas 19
Participantes 7