Ler arquivo TXT

Ola pessoal tudo certo.

Seguinte preciso ler um arquivo texto para tratar os dados porem ele é um pouco grande e da pane de memoria, alguem tem algum exemplo de merge ai para trabalhar com estes arquivos tipo de um arquivo quebrar ele em varios.

Tratar as info e depois gerar o arquivo novamente.

Valeu.

Como estão os dados no seu arquivo?
Mostre um exemplo.

Opa estao assim

nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste
nome;teste;teste;teste;teste;teste

esta é a estrutura

Pelo exemplo deve ser um arquivo no padrão CSV. Você pode tratá-lo assim:

private void carregaDados(String arquivo) throws Exception {
    BufferedReader br = new BufferedReader(new FileReader(arquivo));
    String linha;
    while (br.ready()) {
        linha = br.readLine();
        numeroLinha++;
        processaLinha(linha);
    }
    br.close();
}

Você vai ler linha por linha e tratar cada uma, como no exemplo abaixo:

private void processaLinha(String linha) throws Exception {
	String[] dados = linha.split(";");

	if (dados.length != 3) {
	    throw new Exception("Linha " + numeroLinha + " fora do padrão de importação.");
	}

	Dados d = new Dados();
	d.setValor(dados[0].replace(",", "").trim());
	d.setContaContabil(dados[1].replaceAll("-\d", "").trim());
	d.setTipoLancamento(Character.valueOf(dados[2].trim().charAt(0)));

	adicionaDados(d);

}

:smiley:

vinilima

Qual a diferença técnica em se usar:

       InputStream is = new FileInputStream ("arquivo.txt");
       InputStreamReader isr = new InputStreamReader (is);
       BufferedReader br = new BufferedReader (isr);
		
       String s = br.readLine();
       while (s != null){
           System.out.println (s);
            s = br.readLine();
       }
       br.close();

ou

       BufferedReader br = new BufferedReader (new FileReader("arquivo.txt"));
       
       String s = br.readLine();
       while (s != null){
           System.out.println (s);
            s = br.readLine();
       }
       br.close();

Existe algum tipo de limitação de tamanho de arquivo para se usar a segunda forma? Ou perda de velocidade?
Basicamente, por que ou quando usar a primeiras forma?

Ja tinha respondido antes, sei la mas esta assim:

teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste
teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste
teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste
teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste
teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste
teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste
teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste;teste

A leitura e tratamento em um arquivo pequeno blz o problema é um arquivo grande.

Entao como eu disse é um arquivo grande e qdo eu vou importar ele da estouro de memoria, entende, arquivo pequeno consigo tratar normalmente. li algumas coisas sobre mergesort para este tratamento onde ele abre o arquivo divide ele e depois gera um novo arquivo esquema de “dividir para conquistar”. Quando é arquivo pequeno nao estou tendo nenhum problema.

O problema é nos grandes arquivos.

[quote=mlorenzi]Entao como eu disse é um arquivo grande e qdo eu vou importar ele da estouro de memoria, entende, arquivo pequeno consigo tratar normalmente. li algumas coisas sobre mergesort para este tratamento onde ele abre o arquivo divide ele e depois gera um novo arquivo esquema de “dividir para conquistar”. Quando é arquivo pequeno nao estou tendo nenhum problema.

O problema é nos grandes arquivos.[/quote]

Voce pode usar um buffer de tamanho fixo que resolve.

Olha esse codigo que eu fiz como exemplo:

public static void main(String[] args) { try { FileReader leitor = new FileReader("//home//carlos//arquivo_grande.txt"); BufferedReader buffer = new BufferedReader(leitor, 2 * 1024 * 1024); String linha = buffer.readLine(); while (linha != null) { System.out.print(linha+"\n"); linha = buffer.readLine(); Thread.sleep(1000); } } catch (FileNotFoundException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } catch (InterruptedException ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } }

Eu so coloquei pra dormir ali pra facilitar a visualizacao. Esse meu arquivo de texto so pra fazer um teste tinha 100MB. O meu buffer, como voce pode ver tem 2MB.

Espero ter ajudado.

Hummm.

Vou testar, qual o significado de:

BufferedReader buffer = new BufferedReader(leitor, 2 * 1024 * 1024);

Grato.

Estou passando o FileReader e o outro parametro é o tamanho do buffer, nesse caso, de 2MB.

Um detalhe: deixe o tamanho do buffer de acordo com a sua realidade. Caso voce tenha certeza que vai ler vamos supor 10MB - estou sendo exagerado, ou nao - do arquivo e tenha memoria disponivel para fazer isso sem comprometer o sistema, faça isso. Pq uma das coisas que mais compromete performance é IO e se voce lê tudo de uma vez e em sequencia nao precisa ficar esperando que o disco esteja em uma posicao x pra ler, ja esta tudo carregado na memoria o que minimiza os custos de IO.

Acho que o pessoal não entendeu. Se você está lendo sobre mergeSort, é porque seu trabalho com esse arquivo envolve carrega-lo inteiramente na memória, para então ordena-lo, não?

A sugestão que o pessoal está dando envolve ler apenas linha-a-linha, mas nesse caso, será impossível fazer a ordenação.

A forma mais fácil de resolver isso é carregar esse arquivo numa tabela de um banco de dados, e pedir para o próprio banco ordena-la.

Outra forma é ler apenas o campo que precisa ser ordenado do arquivo e sua posição física (use para isso a classe RandomAccessFile). Ordene essa lista com esses dois campos, e depois use as posições para gerar um novo arquivo ordenado.

A terceira solução não é definitiva como as outras, mas pode quebrar um galho. Se os arquivos grandes não são tão grandes e não tendem a crescer, uma última forma seria aumentar a capacidade máxima de memória da VM. Para isso você inicia o java com o comando -Xmx e quantidade de memória (por padrão é apenas 64MB):

java -Xmx1024m -jar seuPrograma.jar

como o cara ai em cima falou… no seu caso eu utilizaria a terceira opção.
muitos programas fazem isso.
veja por exemplo o arquivo ini do meu eclipse (não foram feitas alterações)

-startup plugins/org.eclipse.equinox.launcher_1.1.1.R36x_v20101122_1400.jar --launcher.library plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.1.2.R36x_v20101019_1345 -product org.eclipse.epp.package.jee.product --launcher.defaultAction openFile -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256m --launcher.defaultAction openFile -vmargs -Dosgi.requiredJavaVersion=1.5 -XX:MaxPermSize=256m -Xms40m -Xmx512m

a revista mundo java numero 35 tem um artigo muito interessante que fala sobre isso. caso vocẽ possa dar uma olhada… fica ai minha dica.

carnaval: se beber, use a camisinha!

Eu usaria a seguinte forma, proposta pelo vini:

carnaval: se beber, use a camisinha!. Se não beber, tb use a camisinha!