Ler um arquivo continuamente

18 respostas
D

Olá galera… estou com a seguinte dúvida:

Tenho 2 arquivos (vou chamar de A e B). Para cada item de A tenho que percorrer o arquivo B inteiro, ou seja, quando chegar no final do arquivo B, tenho que voltar para seu início. E é aqui que está meu problema:
Estou usando BufferedReader para a leitura e não encontrei uma maneira de fazer isso. Já vi os métodos mark e reset, mas não consegui utilizá-los de maneira efetiva nesse contexto.

Agradeço desde já!
Obrigado
Dih_Negretto

18 Respostas

R

Poste o código pra podermos opinar melhor.

Mas já adianto algo, não seria melhor ficar com o arquivo B em memória? já que ele vai ser lido tantas vezes.

D

Rodrigo Sasaki:
Poste o código pra podermos opinar melhor.

Mas já adianto algo, não seria melhor ficar com o arquivo B em memória? já que ele vai ser lido tantas vezes.


Penso da mesma forma. Fica mais fácil trabalhar desta forma, no meu entender.

D
Rodrigo Sasaki:
Poste o código pra podermos opinar melhor.

Mas já adianto algo, não seria melhor ficar com o arquivo B em memória? já que ele vai ser lido tantas vezes.

O problema de ficar com o arquivo B em memória é que ele é muito grande (mais de 100 Mb), sendo assim, pensei que lendo "linha-a-linha" seja a melhor solução. Assim está no main:
if (linhaA != null)
        	{
        		do{
        			linhaB = arq_B.leArquivo(arq_B.getBufferReader(path_leitura_B));
        			
        			if (linhaA == linhaB)

            			arq_A.escreveArquivo(arq_A.getBufferWriter(path_escrita),linhaA);
        			
        		}while(linhaB != null);
Esse é o método que fiz para ler uma linha:
public String leArquivo(BufferedReader buff) throws IOException{
		String linha = "";
		
		linha = buff.readLine();
		return linha;
		
	}
Esse é o método para retornar o bufferReader (o método para retornar o bufferWriter é igual):
public BufferedReader getBufferReader(String path_leitura) throws FileNotFoundException
	{
		if (buffReader == null)
			//Diretório do arquivo de leitura.
			buffReader = new BufferedReader(new FileReader(path_leitura));
		
		return buffReader;
	}
R

Bom, nesse caso eu seguiria o princípio KISS.

Simplesmente instancie o BufferedReader de novo a cada leitura. Não se preocupe com otimização antes do tempo. Caso você verifique que essa operação realmente tem um custo maior do que você está disposto a pagar, aí procure otimizar.

D

Rodrigo Sasaki:
Bom, nesse caso eu seguiria o princípio KISS.

Simplesmente instancie o BufferedReader de novo a cada leitura. Não se preocupe com otimização antes do tempo. Caso você verifique que essa operação realmente tem um custo maior do que você está disposto a pagar, aí procure otimizar.

Segui seu conselho: instanciei o BufferedReader de novo a cada leitura e funcionou. Ainda não testei com o arquivo de 100Mb, mas como você mesmo disse, não vou me preocupar com a otimização antes do tempo.

Muito obrigado pela ajuda =)

D

Rodrigo Sasaki:
Bom, nesse caso eu seguiria o princípio KISS.

Simplesmente instancie o BufferedReader de novo a cada leitura. Não se preocupe com otimização antes do tempo. Caso você verifique que essa operação realmente tem um custo maior do que você está disposto a pagar, aí procure otimizar.


Pode ser controverso, mas, talvez manter essa quantidade de dados em memória custe menos que reler todas as vezes.

D

drsmachado:
Rodrigo Sasaki:
Bom, nesse caso eu seguiria o princípio KISS.

Simplesmente instancie o BufferedReader de novo a cada leitura. Não se preocupe com otimização antes do tempo. Caso você verifique que essa operação realmente tem um custo maior do que você está disposto a pagar, aí procure otimizar.


Pode ser controverso, mas, talvez manter essa quantidade de dados em memória custe menos que reler todas as vezes.

Vou finalizar o programa e depois vou realizar esses testes e comparar o desempenho. =)

Muito obrigado!

R

É, eu pensei nisso também, e em termos de performance, tenho quase certeza que será mais rápido. IO é custoso demais.

H
100 MB que raio de ficheiro é esse?

o mais simples seria colocar isso num do while

ex:

do

{

 le 1 linha arquivo a

ler arquivo b(completo)

}while(arquivo a nao chegar fim)

Assim ira ler 1 linha arquivo a(todo arquivo b) sempre ate chegar ao fim do arquivo A

Ajuda?

D
<blockquote><div class="quote-author">hmpds:</div>100 MB que raio de ficheiro é esse?

o mais simples seria colocar isso num do while

ex:

do

{

… le 1 linha arquivo a

…ler arquivo b(completo)

}while(arquivo a nao chegar fim)

Assim ira ler 1 linha arquivo a(todo arquivo b) sempre ate chegar ao fim do arquivo A

Ajuda?

Os arquivos são sequências de DNA, pois trabalho com Bioinformática. =)
Ali no código que mostrei já tem um do-while … e a dica do Rodrigo Sasaki resolveu meu problema para voltar para a 1ª linha (eu instancio de novo o BufferedReader toda a vez que o arquivo B acaba… Assim que eu finalizar o código eu vou realizar os testes para ver a performance.

Obrigado

E

100 MB não é um arquivo tão grande assim.
Basta você usar as opções corretas para iniciar um programa Java (ou você ainda acredita que dar um duplo-clique em um Jar já faz toda a mágica? )
De qualquer maneira, parece meio bizarro você comparar uma sequência com 100MB de dados sem que esses 100MB não tenham sido indexados de uma forma eficiente. O arquivo que você chamou de “A” é muito grande?

L

Neste caso não existe bala de prata nem luz no fim do tunel porem se eu tivese que ler um arquivo continuo e redirecionar ou ler para outro utilizaria o PERL e o resultado exportava para o JAVA

D

entanglement:
100 MB não é um arquivo tão grande assim.
Basta você usar as opções corretas para iniciar um programa Java (ou você ainda acredita que dar um duplo-clique em um Jar já faz toda a mágica? )
De qualquer maneira, parece meio bizarro você comparar uma sequência com 100MB de dados sem que esses 100MB não tenham sido indexados de uma forma eficiente. O arquivo que você chamou de “A” é muito grande?

Bem, em se tratando de sequências de DNA, creio que o A tenha tamanho parecido com B.

D

O problema é o ambiente onde isso vai rodar, não?
Talvez não seja viável ou possível seguir este caminho.

L

HUmmm… talvez vc possa utilizar a classe nio no lugar da io:
http://www.guj.com.br/articles/118

E

NIO, para um arquivo-texto, normalmente é um problema, não uma solução.

Se a máquina tiver memória suficiente, na segunda vez que o arquivo for relido, provavelmente ele acabará ficando todo em cache do sistema operacional, então a segunda leitura será mais rápida que a primeira.

L

entanglement:
NIO, para um arquivo-texto, normalmente é um problema, não uma solução.

Se a máquina tiver memória suficiente, na segunda vez que o arquivo for relido, provavelmente ele acabará ficando todo em cache do sistema operacional, então a segunda leitura será mais rápida que a primeira.

Ola entanglement!

por curiosidade tava dando uma lida nisso:

O mapeamento é liberado quando o objeto do buffer é recolhido pelo Garbage Colector (e não quando fechamos o channel).

Pensei nessa solução pela performance. Mandar pra memória e ler em blocos na posição pedida. Fiz issouma vez e achei muito bom.
O problema continuaria ocorrendo se escolhêssemos tamanhos de blocos menores?

teríamos que ver o fonte pra ver se vale a pena num teste de performance. Um exemplo:
http://roseindia.net/tutorial/java/corejava/nio/GetIndexValue.html

D

Eu consegui resolver meu problema. O código que fiz rodou em 3hs e meia para arquivo com 195Mb. Um tempo que posso gastar, mas que também posso diminuir.

O que eu pensei: Excluir as linhas que já copiei para o 3º arquivo, assim, a cada laço eu percorrerei 1 sequência a menos (por volta de 5 linhas cada sequencia). Sendo assim, o arquivo de consulta começa com 195Mb e vai diminuindo conforme eu vou encontrando as sequencias.

Vocês tem alguma dica de como eu consiga excluir essas linhas?

Obrigado

Criado 4 de julho de 2013
Ultima resposta 10 de jul. de 2013
Respostas 18
Participantes 7