Leitura de Arquivo TXT

Pessoal,

é uma pergunta bem idiota, mas não sei como fazer…

Seguinte, preciso comparar duas linhas do arquivo txt, tipo, se a próxima linha for igual a anterior, deleta a linha.

alguem pode ajudar ?

Que tal assim?

[code]public void manipularArquivoTexto(String caminho) throws IOException {

List<String> linhasArquivo, linhasModificadas;
String linhaAtual;

// LER OS DADOS DO ARQUIVO...
File file = new File(caminho);
FileReader fileReader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(fileReader);

while (bufferedReader.ready()) {
    linhasArquivo.add(bufferedReader.readLine());
}

bufferedReader.close();
fileReader.close();

// MANIPULAR OS DADOS DO ARQUIVO...
linhaAtual = "";
for (String linha : linhasArquivo) {

    if (!linhaAtual.equals(linha)) {
        linhasModificadas.add(linha);
    }
    linhaAtual = linha;
}

// SALVAR OS DADOS NO ARQUIVO ATUAL...
FileWriter fileWriter = new FileWriter(file);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

bufferedWriter.flush();
for (String linhaModificada : linhasModificadas) {
    bufferedWriter.write(linhaModificada);
}

bufferedWriter.close();
fileWriter.close();

file = null;

}[/code]

Isso resolve?

Poxa Nicolas…sem palavras…

e se resolve…

Brigadão…

Abs,

Nicolas, aproveitando:

Após a leitura do arquivo, eu adicionei um sort conforme abaixo para tentar ordenar o meu arquivo,porém na impressão do novo arquivo, ele esta todo bagunçado. o que será que ocorre ?

   // LER OS DADOS DO ARQUIVO...   
	    File file = new File(caminho);   
	    FileReader fileReader = new FileReader(file);   
	    BufferedReader bufferedReader = new BufferedReader(fileReader);   
	  
	    while (bufferedReader.ready()) {   
	        linhasArquivo.add(bufferedReader.readLine());   
	    }   
	  
	    Collections.sort(linhasArquivo);

E o meu arquivo é neste formato:

IY    IY1KD065    28508    07:33             COND 0012                140711    140711    
DC    DCBK516A    27016    07:23             ABENDED S04C             140711    140711    
DC    DCBK516B    27017    07:23             ABENDED S04C             140711    140711    
DC    DCBK516C    27018    07:23             ABENDED S04C             140711    140711    

Eu preciso ordenar este arquivo pela terceira coluna que são os ID´s. Já me disseram para usar um comparable ou comparator(acho que é isso), mas não entendi muito a lógica do processo não.

dá para me ajudar com mais esta ?

Mais uma vez, obrigado,

Opa!
Você pode criar uma classe que represente esse seu arquivo.

[code]public class MinhaClasseDoArquivoTexto {

public String campo1;
public String campo2;
public Long id;
//...

}[/code]

A cada linha que você receber do arquivo, você manipula a fim de criar uma coleção de objetos:

File file = new File(caminho);  
FileReader fileReader = new FileReader(file);  
BufferedReader bufferedReader = new BufferedReader(fileReader);  
  
List&lt;MinhaClasseDoArquivoTexto&gt; dados = new ArrayList&lt;MinhaClasseDoArquivoTexto&gt;();
while (bufferedReader.ready()) {  
     String linhaArquivo = bufferedReader.readLine();  
     String[] dadosLinha = linhaArquivo.split( /*Qual o delimitador de campos que você usa? Coloque-o aqui.*/ );
    
     MinhaClasseDoArquivoTexto dado = new MinhaClasseDoArquivoTexto();
     dado.setCampo1(dadosLinha[0]);
     dado.setCampo2(dadosLinha[1]);
     dado.setID(Integer.valueOf(dadosLinha[2]));  //&lt;--- seu ID preenche aqui.
     
     dados.add(dado); // adiciona o objeto que representa a linha lida do arquivo.
}  
  
bufferedReader.close();  
fileReader.close();

// AO FINAL, TEMOS UMA COLEÇÃO DAS LINHAS, SEPARADAS EM CADA OBJETO DA LISTA.
// E, FINALMENTE...

Collections.sort(dados, new Comparator&lt;MinhaClasseDoArquivoTexto&gt;() {

    public int compare(MinhaClasseDoArquivoTexto objeto1, MinhaClasseDoArquivoTexto objeto2) {
        return objeto1.getID() == objeto2.getID();
    }
});

Que acha dessa solução?

Show…

Ficou até mais fácil de entender o comparator… brigadão mesmo…

Agora só para fechar, quando vou criar a minha classe com os atributos do meu arquivo TXT, é obrigatorio criar os Getters e setters para trabalhar com estes atributos? ou não é necessário neste caso específico do arquivo TXT ?

vlw

[quote=brunosardao]Show…

Ficou até mais fácil de entender o comparator… brigadão mesmo…

Agora só para fechar, quando vou criar a minha classe com os atributos do meu arquivo TXT, é obrigatorio criar os Getters e setters para trabalhar com estes atributos? ou não é necessário neste caso específico do arquivo TXT ?

vlw[/quote]

Mesmo que não seja obrigatório, é uma boa prática manter getters e setters, isso é convenção do java.
Se amanhã ou depois você precisar usar alguma api do java, terá de fazer isso…
O custo é mínimo, as IDEs geram isso pra vc.

[]'s

Obrigado JM4X .

È bom saber disso. Desta forma vou aplicar eles em minha classe.

Vlw…

Só cuidado com o abuso dos Getters e Setters, o item 15 do livro de Joshua Bloch (Effective Java) diz que devemos reduzir a mutabilidade dos nosso objetos.

Mantenha, por hora, só os getters e setters para os atributos da sua classe. Esse conceito se chama encapsulamento de dados, onde você acessa os atributos indiretamente através de métodos que fazem isso pra você (que são os getters e setters da classe).

Pessoal,

o meu arquivo TXT que estou lendo, esta no formato abaixo:

1BMC SOFTWARE INC.                        IOA KEY-STROKE REPORTING LANGUAGE   (REL 6.3.07)      DATE 01/08/11 TIME 07.10 PAGE 000001

                          I  O  A  -  L  O  G     -   O F   M E S S A G E ( S )

  DATE   TIME   ODATE  USERID   CODE    ------ M E S S A G E --------------------


  310711 000002 300711 CTMG     SEL203I JOB LLBJD490 OID=X6R43 ELIGIBLE FOR RUN
  310711 000002 290711 CTMG     SEL203I JOB MPBJ7E70 OID=X5UCQ ELIGIBLE FOR RUN
  310711 000002 300711 CTMG     SEL203I JOB YABJ0468 OID=X6PVA ELIGIBLE FOR RUN
  310711 000002 300711 CTMG     SEL203I JOB PGBJD470 OID=X6R8A ELIGIBLE FOR RUN
  310711 000002 300711 CTMG     SEL203I JOB PGBJD490 OID=X6R8B ELIGIBLE FOR RUN

como posso fazer para que o leitor leia apenas as linhas com os dados que sáo da linha 8 a 12 e pule as linhas em branco e que tenham cabeçalho, conforme exemplo acima?

Obrigado

[quote=brunosardao]Pessoal,

o meu arquivo TXT que estou lendo, esta no formato abaixo:

1BMC SOFTWARE INC.                        IOA KEY-STROKE REPORTING LANGUAGE   (REL 6.3.07)      DATE 01/08/11 TIME 07.10 PAGE 000001

                          I  O  A  -  L  O  G     -   O F   M E S S A G E ( S )

  DATE   TIME   ODATE  USERID   CODE    ------ M E S S A G E --------------------


  310711 000002 300711 CTMG     SEL203I JOB LLBJD490 OID=X6R43 ELIGIBLE FOR RUN
  310711 000002 290711 CTMG     SEL203I JOB MPBJ7E70 OID=X5UCQ ELIGIBLE FOR RUN
  310711 000002 300711 CTMG     SEL203I JOB YABJ0468 OID=X6PVA ELIGIBLE FOR RUN
  310711 000002 300711 CTMG     SEL203I JOB PGBJD470 OID=X6R8A ELIGIBLE FOR RUN
  310711 000002 300711 CTMG     SEL203I JOB PGBJD490 OID=X6R8B ELIGIBLE FOR RUN

como posso fazer para que o leitor leia apenas as linhas com os dados que sáo da linha 8 a 12 e pule as linhas em branco e que tenham cabeçalho, conforme exemplo acima?

Obrigado[/quote]

Bom, as linhas de dados tem um padrão, certo?
Por exemplo: “CAMPO1 [DELIMITADOR] CAMPO2 [DELIMITADOR] CAMPO 3”

Portanto, você pode definir um formato padrão para as linhas de dado.
Você lê uma linha do arquivo. Usa um split() para dividir a linha em vários campos separadas pelo seu delimitador.
Daí você confere: a linha lida satisfaz a condição padrão?
Se sim, você manipula ela; se não, descarta-a.

O que acha?

Opa Nicolas…

Show de bola a sua ideia…

Tem sim, eu uso o split, com o parâmetro " " (Espaço).

exemplo:


  while((leitor=reader.readline()) != null){

        String arquivoAbend = leitor;       
        String[] novoArq = arquivoAbend.split(" ");       

Para manipular da forma que você fala, eu deveria usar o parametro novoArq que eu crio acima para identificar as informações ?

Ou usaria a opção “leitor” para fazer isso ?

Obrigado,

[quote=brunosardao]Opa Nicolas…

Show de bola a sua ideia…

Tem sim, eu uso o split, com o parâmetro " " (Espaço).

exemplo:


  while((leitor=reader.readline()) != null){

        String arquivoAbend = leitor;       
        String[] novoArq = arquivoAbend.split(&quot; &quot;);       

Para manipular da forma que você fala, eu deveria usar o parametro novoArq que eu crio acima para identificar as informações ?

Ou usaria a opção "leitor" para fazer isso ?

Obrigado,
[/quote]

Cara, essa é a linha do seu arquivo:

310711 000002 300711 CTMG     SEL203I JOB LLBJD490 OID=X6R43 ELIGIBLE FOR RUN

Então, nós temos 9 campos:

Campo 1 - 310711;
Campo 2 - 000002;
Campo 3 - 300711;
Campo 4 - CTMG;
Campo 5 - SEL203I;
Campo 6 - JOB;
Campo 7 - LLBJD490;
Campo 8 - OID=X6R43;
Campo 9 - ELIGIBLE FOR RUN;

Então, ao usar o split, você gera um array com 9 campos.
[Aconselho a usar algo como $ ou # como delimitador dos campos. Espaço é meio tenso na hora de separar o campo 9.]
Vamos supor que a sua linha seja:

310711#000002#300711#CTMG#SEL203I#JOB LLBJD490#OID=X6R43#ELIGIBLE FOR RUN

Então, você poderia analisar desse modo:

while((leitor=reader.readline()) != null) {  
  
      String arquivoAbend = leitor;         
      String[] novoArq = arquivoAbend.split(&quot;#&quot;); //&lt;--- esse é o array separado.

      if (novoArq.lenght() == 9) { // se ele tiver 9 campos como deveria ter a linha...
          // processamento...
      }
}

Sacou?

Não precisa falar mais nada…:slight_smile:

Jà entendi Nicolas, legal, vou testar novamente a codificação do meu programa.

Estou seguindo aquele esquema que você tinha me mostrado, criando uma classe que representa o meu arquivo e setando nos atributos as informações do meu arquivo.

Porém, ta ocorrendo erro de ArrayIndexOutOfBounds, possivelmente por causa das linhas diferentes, vazias, com dados errados, coisas do tipo…

Por isso, vou seguir este esquema que você mostrou…obrigado mais uma vez…

Groovin
Obrigado pela dica, vou ver depois o site…

Nicolas ou todos…

O meu codigo esta desta forma:


	 List&lt;Colunas_Arquivo&gt; col = new ArrayList&lt;Colunas_Arquivo&gt;();
		
		 String linha = null;
		 
		  while((linha = buff.readLine())!= null){
		    	
	 
		   String lineArq = buff.readLine();           // LE O ARQUIVO LINHA A LINHA
		   String [] dadosArq = lineArq.split(&quot; &quot;); // SEPARA O ARQUIVO EM COLUNAS
		    	
		   System.out.println(retornaListaNumerada(dadosArq));
		   
		   
		      // CRIA UMA INSTANCIA DA CLASSE COLUNAS_ARQUIVO PARA MANIPULACAO DOS DADOS 	
		      Colunas_Arquivo dados = new Colunas_Arquivo();
		     
		      
		      if(dadosArq.length == 19){ // LIMITA A QUANTIDADE DE CAMPOS PARA BUSCAR OS DADOS
		      		      
		      // DETERMINA AS INFORMACOES NECESSARIAS
		      if(buff.readLine().contains(&quot;ABENDED&quot;) || buff.readLine().contains(&quot;FAILED&quot;) ||
		         buff.readLine().contains(&quot;UNEXPLA&quot;) ||  buff.readLine().contains(&quot;NOT CATLGD&quot;)){
		   
		    	  
		      // JOBNAME SOMENTE COM 8 POSICOES e ODATE IGUAL AO ESCOLHIDO	  
		      if(dadosArq[13].length() &gt; 8 && dadosArq[4].equals(&quot;020811&quot;) ){	  
			    	 	       
		    	  
		      // SETA OS DADOS NAS VARIAVEIS DA CLASSE COLUNAS_ARQUIVO
		      dados.setSigla_sistema(dadosArq[13].substring(0,2));
		      dados.setNome_Job(dadosArq[13].substring(0,8));
		      dados.setNum_ID_Job(dadosArq[13].split(&quot;/&quot;)[1]);
		      dados.setHr_Inicial(dadosArq[3]);
		      dados.setOdate_Processamento(dadosArq[4]);
		      dados.setData_Processamento(dadosArq[2]);
		      
		      
		      // PARTE DAS OCORRENCIAS
		      if(buff.readLine().contains(&quot;ABENDED&quot;)){
		      	  dados.setOcorrencia(dadosArq[15] + &quot; &quot; + dadosArq[16] + &quot; &quot; + dadosArq[17]);   
		      }else if (buff.readLine().contains(&quot;FAILED&quot;)){
		    	  dados.setOcorrencia(dadosArq[15] + &quot; &quot; + dadosArq[16] + &quot; &quot; + dadosArq[17]);
		      }else if (buff.readLine().contains(&quot;NOT CATLGD 2&quot;)){
		    	  dados.setOcorrencia(dadosArq[15] + &quot; &quot; + dadosArq[16] + &quot; &quot; + dadosArq[17] + &quot; &quot; + dadosArq[18] + &quot; &quot; + dadosArq[19]);
		      }else if (buff.readLine().contains(&quot;UNEXPLA&quot;)){
		    	  dados.setOcorrencia(dadosArq[16] + &quot; &quot; + dadosArq[18]);
		      }
		      
		      }}}
		      
		      
		      // ADICIONA NA LIST OS DADOS
		      col.add(dados);
	    
		     
		 } // WHILE
		 
	
	 PrintWriter bw = new PrintWriter(new File(&quot;out.txt&quot;));     
         
         for(Colunas_Arquivo dados : col){   
                 bw.println(dados);  
                 
         }        

Porem, quando mando imprimir no arquivo, não sai os valores e sim somente as informações abaixo:

Estrutura.Colunas_Arquivo@13a66c87
Estrutura.Colunas_Arquivo@131f1d25
Estrutura.Colunas_Arquivo@5fb271f1
Estrutura.Colunas_Arquivo@3c56b64c
Estrutura.Colunas_Arquivo@60da5686

o que estou fazendo de errado ?

Obrigado.

[quote=brunosardao]Nicolas ou todos…

O meu codigo esta desta forma:


	 List&lt;Colunas_Arquivo&gt; col = new ArrayList&lt;Colunas_Arquivo&gt;();
		
		 String linha = null;
		 
		  while((linha = buff.readLine())!= null){
		    	
	 
		   String lineArq = buff.readLine();           // LE O ARQUIVO LINHA A LINHA
		   String [] dadosArq = lineArq.split(&quot; &quot;); // SEPARA O ARQUIVO EM COLUNAS
		    	
		   System.out.println(retornaListaNumerada(dadosArq));
		   
		   
		      // CRIA UMA INSTANCIA DA CLASSE COLUNAS_ARQUIVO PARA MANIPULACAO DOS DADOS 	
		      Colunas_Arquivo dados = new Colunas_Arquivo();
		     
		      
		      if(dadosArq.length == 19){ // LIMITA A QUANTIDADE DE CAMPOS PARA BUSCAR OS DADOS
		      		      
		      // DETERMINA AS INFORMACOES NECESSARIAS
		      if(buff.readLine().contains(&quot;ABENDED&quot;) || buff.readLine().contains(&quot;FAILED&quot;) ||
		         buff.readLine().contains(&quot;UNEXPLA&quot;) ||  buff.readLine().contains(&quot;NOT CATLGD&quot;)){
		   
		    	  
		      // JOBNAME SOMENTE COM 8 POSICOES e ODATE IGUAL AO ESCOLHIDO	  
		      if(dadosArq[13].length() &gt; 8 && dadosArq[4].equals(&quot;020811&quot;) ){	  
			    	 	       
		    	  
		      // SETA OS DADOS NAS VARIAVEIS DA CLASSE COLUNAS_ARQUIVO
		      dados.setSigla_sistema(dadosArq[13].substring(0,2));
		      dados.setNome_Job(dadosArq[13].substring(0,8));
		      dados.setNum_ID_Job(dadosArq[13].split(&quot;/&quot;)[1]);
		      dados.setHr_Inicial(dadosArq[3]);
		      dados.setOdate_Processamento(dadosArq[4]);
		      dados.setData_Processamento(dadosArq[2]);
		      
		      
		      // PARTE DAS OCORRENCIAS
		      if(buff.readLine().contains(&quot;ABENDED&quot;)){
		      	  dados.setOcorrencia(dadosArq[15] + &quot; &quot; + dadosArq[16] + &quot; &quot; + dadosArq[17]);   
		      }else if (buff.readLine().contains(&quot;FAILED&quot;)){
		    	  dados.setOcorrencia(dadosArq[15] + &quot; &quot; + dadosArq[16] + &quot; &quot; + dadosArq[17]);
		      }else if (buff.readLine().contains(&quot;NOT CATLGD 2&quot;)){
		    	  dados.setOcorrencia(dadosArq[15] + &quot; &quot; + dadosArq[16] + &quot; &quot; + dadosArq[17] + &quot; &quot; + dadosArq[18] + &quot; &quot; + dadosArq[19]);
		      }else if (buff.readLine().contains(&quot;UNEXPLA&quot;)){
		    	  dados.setOcorrencia(dadosArq[16] + &quot; &quot; + dadosArq[18]);
		      }
		      
		      }}}
		      
		      
		      // ADICIONA NA LIST OS DADOS
		      col.add(dados);
	    
		     
		 } // WHILE
		 
	
	 PrintWriter bw = new PrintWriter(new File(&quot;out.txt&quot;));     
         
         for(Colunas_Arquivo dados : col){   
                 bw.println(dados);  
                 
         }        

Porem, quando mando imprimir no arquivo, não sai os valores e sim somente as informações abaixo:

Estrutura.Colunas_Arquivo@13a66c87
Estrutura.Colunas_Arquivo@131f1d25
Estrutura.Colunas_Arquivo@5fb271f1
Estrutura.Colunas_Arquivo@3c56b64c
Estrutura.Colunas_Arquivo@60da5686

o que estou fazendo de errado ?

Obrigado.[/quote]

Duas coisas:

  1. Caminhe nos valores do seu array ao invés de ler, ler e reler os dados com o readLine().
while((linha = buff.readLine())!= null) {

    String lineArq = buff.readLine();           // LE O ARQUIVO LINHA A LINHA
    String [] dadosArq = lineArq.split(&quot; &quot;); // SEPARA O ARQUIVO EM COLUNAS

    Colunas_Arquivo dados = new Colunas_Arquivo();
    Boolean podeProcessar = false;

    if(dadosArq.length() == 19) {
        
        for (String dado : dadosArq) {

            if(dado.toUpperCase().contains("ABENDED") || dado.toUpperCase()..contains("FAILED") ||
	        dado.toUpperCase().contains("UNEXPLA") ||  dado.toUpperCase().contains("NOT CATLGD"))		   
	    	       podeProcessar = true;
   
        }

        if (podeProcessar) {

            if (dadosArq[13].length() == 8 && dadosArq[4].equals("020811")) {

	        dados.setSigla_sistema(dadosArq[13].substring(0,2));
	        dados.setNome_Job(dadosArq[13].substring(0,8));
		    dados.setNum_ID_Job(dadosArq[13].split(&quot;/&quot;)[1]);
		    dados.setHr_Inicial(dadosArq[3]);
		    dados.setOdate_Processamento(dadosArq[4]);
		    dados.setData_Processamento(dadosArq[2]);
		      
                for (String dado : dadosArq) {

                    if(dado.toUpperCase().contains("ABENDED")) {
		      	  dados.setOcorrencia("teu valor"); 
                    }
                    else if (dado.toUpperCase().contains("FAILED") {
                          dados.setOcorrencia("teu valor"); 
                    }
                    //...
                }
            }   
        }   
    }  
  1. Sobrescreva o método toString() da sua classe Colunas_Arquivo para imprimir o que você precisa!

Putz Nicolas, esqueci o método toString() na minha classe do arquivo…hehe.

Bom, se eu lembro é este abaixo certo ?


  public String toString(){   
        return "XXXXX+ " " + YYYYY + " ";   // Aqui eu adiciono os atributos da minha classe para serem impressos certo ?

Depois disso, na saida do meu arquivo, eu utilizo este método para imprimir nele certo ?

Valew…e obrigado por todo o Help…

[quote=brunosardao]Putz Nicolas, esqueci o método toString() na minha classe do arquivo…hehe.

Bom, se eu lembro é este abaixo certo ?


  public String toString(){   
        return "XXXXX+ " " + YYYYY + " ";   // Aqui eu adiciono os atributos da minha classe para serem impressos certo ?

Depois disso, na saida do meu arquivo, eu utilizo este método para imprimir nele certo ?

Valew…e obrigado por todo o Help…
[/quote]

Na sua classe, dê Ctrl+Space e escreva toString. Ele aparecerá para ser sobrescrito.
Caso queria fazer na mão, a assinatura para sobrescrever o método é:

@Override
public String toString() {

    return super.toString(); // você muda o retorno para qualquer coisa que você quiser imprimir.
}

O método de leitura dos dados que passei no outro post funcionou certinho?
Aliás, muda aqui a sintaxe do seu foreach, é ao contrário.

Ao invés de:

for(Colunas_Arquivo dados : col){ bw.println(dados); }

é:

for (Colunas_Arquivo col : dados) { // onde dados é a coleção e col é o objeto. bw.println(col); }

A blz, legal Nicolas, a saida vou testar agora…

Tava arrumando método toString na minha classe.

vou ver agora e já te posto…o resultado…

valew…