Dúvida ao juntar dois arquivos TXT

35 respostas
E

Bom dia pessoal,
estou fazendo um programa para pegar parte do conteúdo um arquivo X.txt comparar com parte do conteúdo do arquivo Y.txt e se for igual inserir em um arquivo Z.txt

public LerArquivo() throws FileNotFoundException{
		    Scanner leitor = new Scanner(new File("/home/aceneserra/Área de Trabalho/Registro60D.txt"));
		    Scanner sef = new Scanner(new File("/home/aceneserra/Área de Trabalho/SEF022008.txt"));
		    List<String> linhas = new ArrayList<String>();  
		    List<String> linhasSef = new ArrayList<String>();  
		    while (sef.hasNextLine()){
		    	linhasSef.add(sef.nextLine());
		    }
		    sef.close();
		    while (leitor.hasNextLine()) {  
		        linhas.add(leitor.nextLine());  
		    }  
		    leitor.close();  
		      
		    Object[] vetorDeLinhas =  linhas.toArray();  
		    Object[] vetorDeLinhasSef =  linhasSef.toArray();    		

		    for(int i= 0; i<vetorDeLinhas.length; i++){
		    	for(int j=0; j<vetorDeLinhasSef.length; j++){
	   		   	 	
		    		if(vetorDeLinhasSef[j].toString().substring(3, 30).equals(vetorDeLinhas[i].toString().substring(3, 30))){
	   		   	 		System.out.println(vetorDeLinhasSef[j].toString().substring(3, 30)+"   "+vetorDeLinhas[i].toString().substring(3, 30));
	   		   	 	}
		    }
		    }
	   	        	
	}

como eu salvo esses dois arquivo em um só? acho que só falta isso!

35 Respostas

Rodrigo_Sasaki

Crie um PrintWriter, ou BufferedWriter ou seja lá qual for o que você prefere e escreva o texto no seu terceiro arquivo.

Se tem dúvidas sobra a manipulação de arquivos leia este artigo do GUJ.

E

o arquivo X tem 40000 linhas, não mostra todas no console, será se essa minha implementação está correta?

Rodrigo_Sasaki

Algumas IDEs mantém o console com tamanho limitado, você pode ou tirar/alterar esse limite, ou escrever os dados no arquivo e ver se sai como você quer.

E
Gravei o arquivo Z.txr mas ele grava com 3 linhas iguais a cada linha do arquivo X.txt, e não grava todas as 40000 grava só 126. acho que minha lógica desse for ta errada, poderia me ajudar?
FileWriter fw = new FileWriter("/home/aceneserra/Área de Trabalho/SAIU.txt");  
		   	BufferedWriter bw = new BufferedWriter(fw); 
if(vetorDeLinhasSef[j].toString().substring(3, 30).equals(vetorDeLinhas[i].toString().substring(3, 30))){
	   		   	 		
		    			bw.write(vetorDeLinhas[i].toString());
		    			
	   		   	 	} 
  bw.close();
Rodrigo_Sasaki

A string retornada nas duas chamadas ao substring() realmente são iguais nas 40000 linhas?

E

Não, acho que me expressei mal!

eu pego as linhas do arquivo X(40000) uma por uma comparo com as linhas do arquivo Y (30), se forem iguais adiciono as duas no arquivo Z!

Da pra entender? :?

Rodrigo_Sasaki

Tudo bem, mas minha pergunta ainda é válida.

Quantas linhas você quer que sejam impressas no arquivo Z? tem uma ideia ou uma média?

Esse no caso não seria o resultado correto ?

E

Uma média de 100 substrings(linhas) do arquivo X iguais 1 substring do arquivo Y

E

O console do Eclipse (você está usando o Eclipse) ou o console do Windows costuma mostrar apenas uma quantidade limitada de linhas, para evitar problemas de estourar a memória.

E
Por exemplo 

conteudo X.txt                                       conteudo Y.txt                                    conteudo Z.txt
apenas substring(3,31)                        apenas substring(3,31)                      string completa
2008010100001                                   2008010100001                                 60M 2008010100001.....
2008010100001                                   2008010101212                                 60A 2008010100001.........
2008010100001                                   2009999999991                                 60D  2008010100001.........
2008010100001                                                                                              60D  2008010100001.......
2009999999991                                                                                              60D  2008010100001.......
2009999999991                                                                                              60D  2008010100001.......
                                                                                                                        60M 2009999999991....
                                                                                                                        60A 2009999999991.....
                                                                                                                        60D2009999999991.....
                                                                                                                        60D 2009999999991...

os que começam com 60D fazem parte do arquivo X e os com 60M e 60A do Y!

E

É eu uso o eclipse no Linux :slight_smile:

E

Alguém poderia me ajuda?

E

Alguém tem uma outra solução para se juntar esses dois arquivos?

Rodrigo_Sasaki

tentou dar um trim depois do substring pra ver se resolve? não sei se existem espaços sobrando por aí

E
Cara, andei pesquisando, e vi que usar I/O para arquivos enormes não é muito bom, recomenda-se usar a new I/O comecei a fazer aqui denovo, mas me surgiu uma dúvida aqui (coisa de principiante)
public Pegar() throws IOException{
			 // Cria a stream para ler o arquivo original  
			   FileInputStream fin = new FileInputStream("/home/aceneserra/Área de Trabalho/Registro60D.txt");
			   FileInputStream sef = new FileInputStream("/home/aceneserra/Área de Trabalho/SEF022008.txt");
			 
			      
			   // Cria a stream para gravar o arquivo de cópia  
			   FileOutputStream fout = new FileOutputStream("/home/aceneserra/Área de Trabalho/SAIDA.txt");  
			     
			   // Usa as streams para criar os canais correspondentes  
			   FileChannel in = fin.getChannel();  
			   FileChannel inSef = sef.getChannel(); 
			   FileChannel out = fout.getChannel();  
			  
			   // Número de bytes do arquivo original  
			   long numbytes = in.size();         
			   long numbytes1 = inSef.size();         
			     
			  
			   // Transfere todo o volume para o arquivo de cópia.   
			   in.transferTo(0, numbytes, out);
			   inSef.transferTo(0,numbytes1,out);   
		}

Como eu faço pra colocar esse valores em uma String pra poder passar o Split e quebrar linha por linha?

E

Bom dia pessoal, ontem implementei uma outra solução que acredito que está quase lá!! :D

public static void main(String[] args) throws FileNotFoundException, IOException{
	    Scanner arquivo = new Scanner(new File("/home/aceneserra/Área de Trabalho/SEF022008.txt"));
	    Scanner arquivo2 = new Scanner(new File("/home/aceneserra/Área de Trabalho/Registro60D.txt"));
	      	
	        List<String> listaSef = new ArrayList<String>();  
	        List<String> lista60D = new ArrayList<String>();

	        while (arquivo.hasNextLine()) {  
	                   listaSef.add(arquivo.nextLine());  
	               }  
	               while (arquivo2.hasNextLine()) {  
	                   lista60D.add(arquivo2.nextLine());  
	               }  
	               	for(int i=0; i<lista60D.size(); i++){
	               		for (int j=0;j<listaSef.size();j++){
	               			if(lista60D.get(i).substring(3, 30).equals(listaSef.get(j).substring(3, 30))){
	               				
	       
	               				salvar("/home/aceneserra/Área de Trabalho/CERTO.txt", lista60D.get(i)+"\n", true);
	               			}
	               			
	               		}
	               		
	               	}
	           
	      }

O problema é que ele salva 3 linhas repetidas de cada linha correta, alguém sabe como resolver esse "probleminha"?

E

Como é o método “salvar” ?

E
public static void salvar(String arquivo, String conteudo, boolean adicionar)
		    throws IOException {

		        FileWriter fw = new FileWriter(arquivo, adicionar);

		        fw.write(conteudo);
		        fw.close();
		    }
E

O programa abaixo deve fazer a mesma coisa que você está querendo fazer, mas de maneira mais rápida e que gasta bem menos memória. Isso pode ser importante se você tem um arquivo “Registro60D.txt” com mais de 16 MB de tamanho…

import java.io.*;
import java.util.*;

public class Exemplo {
    public static void main (String[] args) throws IOException {
		File arquivoSEF = new File ("/home/aceneserra/Área de Trabalho/SEF022008.txt");
		File arquivoEntrada = new File ("/home/aceneserra/Área de Trabalho/Registro60D.txt");
		File arquivoSaida = new File ("/home/aceneserra/Área de Trabalho/CERTO.txt");
		
		// Carregando a lista de códigos do arquivo da SEF
		BufferedReader sef = new BufferedReader (new FileReader (arquivoSEF));
		SortedSet <String> codigosSEF = new TreeSet <String> ();
		for (String linha = sef.readLine(); linha != null; linha = sef.readLine()) {
			if (linha.length() >= 30)
				codigosSEF.add (linha.substring(3, 30)); 
		}
		sef.close();

		// Lendo o arquivo de entrada e escrevendo no arquivo de saída
		BufferedReader entrada = new BufferedReader (new FileReader (arquivoEntrada));
		PrintWriter saida = new PrintWriter (new BufferedWriter (new FileWriter (arquivoSaida)));
		for (String linha = entrada.readLine(); linha != null; linha = entrada.readLine()) {
			if (linha.length() >= 30) {
				String codigo = linha.substring (3, 30);
				if (codigosSEF.contains (codigo)) {
					saida.println (linha);
				}
			}
		}
		saida.close();
		entrada.close();
	}
}
E

É mais ou menos assim, deixa eu te explicar o que eu quero.

tenho que pegar cada linha do arquivo SEF pego sua subString(3,30) e procuro em cada linha do arquivo Registro60D se encontrar, pego toda a linha do arquivo Registro60D e a coloco no arquivo SEF(eu estou colocando em outro arquivo só para teste) só que ao inserir essa linha, ela vai pro final do arquivo, eu queria que ela ficasse logo abaixo da linha comparada. um exemplo:

60M[color=darkred]200802010000000000000000606[/color]0092D08857708871600048600300000000002756400000000204489046 00002042134060000000272715000000004636200000
60D[color=darkred]200802010000000000000000606[/color]337095 000000000100000000000000053900000000000000000 0000000000000
60D[color=darkred]200802010000000000000000606[/color]336625 000000000100000000000000064900000000000000000 0000000000000
60D[color=darkred]200802010000000000000000606[/color]322961 000000000100000000000000043900000000000000000 0000000000000
60D[color=darkred]200802010000000000000000606[/color]340341 000000000100000000000000049900000000000000000 0000000000000
60D[color=darkred]200802010000000000000000606[/color]338387 000000000100000000000000129900000000000000000 0000000000000
60D[color=darkred]200802010000000000000000606[/color]333915 000000000100000000000000079900000000000000000 0000000000000
60A200802010000000000000000606DESC000000002925
60A2008020100000000000000006061700000000272715
60M20080201SW0107000000000061360102D09718009728000049300400000000002464200000000224096583 00002238501630000000238210000000004049600000
60A20080201SW0107000000000061361700000000238210
60A20080201SW010700000000006136DESC000000008210

onde as linhas que iniciam com 60D fazem parte do arquivo registro60D

E

Esses arquivos possuem milhares de linhas, e tenho que inserir a linha 60D sempre abaixo da linha 60M!

E

Ah, agora entendi. O seu problema é que você está fazendo o relacionamento incorreto (ao contrário que deveria ser).
No seu caso, o arquivo Registro60D é muito grande? Se for grande, então preciso resolver de outro jeito.

E

Me diga o tamanho em bytes aproximado.

E

O arquivo 60D tem mais de 39 mil linhas!

E

Alguma sugestão?

E

39 mil linhas, cada linha com 100 colunas mais ou menos?

Você vai gastar algo como: 39.000 x 100 x 2 (porque cada caracter ocupa 2 bytes no Java), isso quer dizer um pouco menos de 8 megabytes, ou seja, não é nada que você precise acertar a configuração do Java para rodar seu programa. Eu faria algo parecido com o seguinte: (é óbvio que você vai ter de entender o programa e testar, não vou testar o programa para você):

E por favor, aprenda um pouquinho sobre mapas. Eles resolvem um monte de problemas que não se resolvem só com listas.

package guj;

import java.io.*;
import java.util.*;

public class ExemploLeituraArquivoSEF {
    public static void main(String[] args) throws IOException {
        File arquivoSEF = new File("/home/aceneserra/Área de Trabalho/SEF022008.txt");
        File arquivoEntrada = new File("/home/aceneserra/Área de Trabalho/Registro60D.txt");
        File arquivoSaida = new File("/home/aceneserra/Área de Trabalho/CERTO.txt");

        // Carregando o arquivo Registro60D
        BufferedReader reg60D = new BufferedReader(new FileReader(arquivoEntrada));
        SortedMap<String, List<String>> registros60D = new TreeMap<String, List<String>>();
        for (String linha = reg60D.readLine(); linha != null; linha = reg60D.readLine()) {
            if (linha.length() >= 30) {
                String codigo = linha.substring(3, 30);
                List<String> linhasComMesmoCodigo = registros60D.get(codigo);
                if (linhasComMesmoCodigo == null) {
                    linhasComMesmoCodigo = new ArrayList<String>();
                    registros60D.put(codigo, linhasComMesmoCodigo);
                }
                linhasComMesmoCodigo.add(linha);
            }
        }
        reg60D.close();

        // Lendo o arquivo SEF, correlacionando com o arquivo Registro60D, e escrevendo no arquivo de saída
        BufferedReader sef = new BufferedReader(new FileReader(arquivoSEF));
        PrintWriter saida = new PrintWriter(new BufferedWriter(new FileWriter(arquivoSaida)));
        for (String linha = sef.readLine(); linha != null; linha = sef.readLine()) {
            if (linha.length() >= 30) {
                String codigo = linha.substring(3, 30);
                saida.println(linha); // a linha original do arquivo SEF
                List<String> linhasComMesmoCodigo = registros60D.get(codigo);
                if (linhasComMesmoCodigo != null) {
                    for (String linhaReg60D : linhasComMesmoCodigo) {
                        saida.println(linhaReg60D); // cada uma das linhas do arquivo Registro60D que tem o mesmo código
                                                    // que aparece no arquivo SEF
                    }
                }
            }
        }
        saida.close();
        sef.close();
    }
}
E

Uma coisinha. No programa acima, estou supondo que se uma determinada linha do arquivo SEF tiver um código que não aparecer em nenhuma linha do arquivo Registro60D, ela ainda assim deve aparecer no arquivo final. É isso mesmo, ou então se não aparecer no arquivo Registro60D você tem de desprezar essa linha do arquivo SEF?

E

O conteúdo do arquivo SEF continua, o que tenho que fazer é adicionar o conteúdo do arquivo 60D ao SEF com as condições citadas anteriormente!

E

entanglement cara, muito obrigado por tua ajuda, vou seguir sua orientação e entender esse código ai, esse código que voce postou por ultimo está quase certo.
o problema dele é que está repetindo os valores, mas sua ajuda ja foi de grande valor, vou tentar corrigir. Muito obrigado mais uma vez!

E

Esse é o arquivo de saida que está gerando.

E

Essa deveria ser a saida!!!

E

“Ele está repetindo os valores” porque as linhas estão repetidas no arquivo SEF ou porque as linhas estão repetidas em 60D? Não estou com a menor vontade de analisar seu arquivo. Por favor, explique o que está repetido e deixe de ficar chorando porque não sabe pelo menos apontar os erros.

Você não especificou que era para remover as linhas repetidas que estão em 60D :slight_smile:

Se é para tirar as linhas repetidas em 60D, troque as referências a um List (e um ArrayList) que estão no código que postei, por um Set (e LinkedHashSet) . O resto deve ser igualzinho.

http://docs.oracle.com/javase/6/docs/api/java/util/Set.html
http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html

E

Cara eu não estou chorando! :wink:
só postei o arquivo pq pensei que voce quisesse saber o que fez. :thumbup: ja disse que vc ajudou muito e que vou desenrolar o resto.
valeu pela ajuda !

snowblacksoul

E ae Eduardo_nunes blz!
Você já conseguiu resolver o problema?!

Fiz um teste aqui, não sei se é exatamente isso que você gostaria, mas acho que dar um luz, espero que tenha ajudado

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;

public class LerDoisArquivoeComparar {

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

		try {
			// pega os arquivos txt´s
			File file = new File("g:/scripts/CERTO2.txt");
			File file2 = new File("g:/scripts/CERTO1.txt");

			FileReader fileReader = new FileReader(file);
			BufferedReader bufferedReader = new BufferedReader(fileReader);

			FileReader fileReader2 = new FileReader(file2);
			BufferedReader bufferedReader2 = new BufferedReader(fileReader2);

			
				while (bufferedReader.ready()) {

					bufferedReader2.ready();

					String linha = bufferedReader.readLine(); // lê uma linha...
					String linha2 = bufferedReader2.readLine(); // lê uma linha...

					if (linha.toString().equals(linha2.toString())) { // verifica se as linhas são iguais
						System.out.println("igual");
						// #####################################################
						RandomAccessFile raf = new RandomAccessFile(
								"g:/scripts/daniel.txt", "rw");
						raf.seek(raf.length());
						raf.writeBytes(linha + "\r\n");
						raf.close();
						// ######################################################
						System.out.println(linha);
					} else {
						System.out.println("diferente");
					}
				}

			
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

}

abraços

E

snowblacksoul:
E ae Eduardo_nunes blz!
Você já conseguiu resolver o problema?!

Fiz um teste aqui, não sei se é exatamente isso que você gostaria, mas acho que dar um luz, espero que tenha ajudado

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;

public class LerDoisArquivoeComparar {

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

		try {
			// pega os arquivos txt´s
			File file = new File("g:/scripts/CERTO2.txt");
			File file2 = new File("g:/scripts/CERTO1.txt");

			FileReader fileReader = new FileReader(file);
			BufferedReader bufferedReader = new BufferedReader(fileReader);

			FileReader fileReader2 = new FileReader(file2);
			BufferedReader bufferedReader2 = new BufferedReader(fileReader2);

			
				while (bufferedReader.ready()) {

					bufferedReader2.ready();

					String linha = bufferedReader.readLine(); // lê uma linha...
					String linha2 = bufferedReader2.readLine(); // lê uma linha...

					if (linha.toString().equals(linha2.toString())) { // verifica se as linhas são iguais
						System.out.println("igual");
						// #####################################################
						RandomAccessFile raf = new RandomAccessFile(
								"g:/scripts/daniel.txt", "rw");
						raf.seek(raf.length());
						raf.writeBytes(linha + "\r\n");
						raf.close();
						// ######################################################
						System.out.println(linha);
					} else {
						System.out.println("diferente");
					}
				}

			
		} catch (IOException e) {
			throw new RuntimeException(e);
		}

	}

}

abraços

Valeu, toda ajuda é bem vinda…
Mas estou quase terminando!!!

Criado 24 de agosto de 2012
Ultima resposta 5 de set. de 2012
Respostas 35
Participantes 4