Dúvida com Programa para geração de busca multi-nível
10 respostas
marcioluiz
Galera,
Buenas!
Preciso construir um programa aqui no meu estágio, em java, para rodar em linha de comando, que leia uma string (pode ser do tclado inicialmente), busque essa string em um arquivo texto e depois retorne em um treeMap todas as linhas a partir da linha na qual a busca está contida, isso até o segundo “;” (semicollon).
Bem pesquisei bastante e cheguei até aqui:
packagebuscacarteiras;importjava.awt.HeadlessException;importjava.io.BufferedReader;importjava.io.File;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.IOException;importjava.util.Iterator;importjava.util.Set;importjava.util.TreeMap;importjava.util.Scanner;publicclassScript_Listagem{publicstaticvoidmain(String[]args){// Lê do teclado o nome da windowScannerdados=newScanner(System.in);System.out.println("Digite o nome da window: ");// leitura da windowStringwindow=dados.next();System.out.println("Listagem da window: "+window);FileReaderfr=null;BufferedReaderbr=null;StringBuffersb=null;// endereco do arquivoStringCAM_AQ_WD="c:/"+"unifiles/"+"Coms-Window.txt";try{// sring que armazena a windowStringoQueProcuro=window;// Declaracao do TreeMap que armazena a windowTreeMap<String,String>mapaWindow=newTreeMap<String,String>();// leitura do arquivo windowFilef=newFile(CAM_AQ_WD);fr=newFileReader(f);br=newBufferedReader(fr);sb=newStringBuffer(5000);Stringlinha="";StringEntidadeWin=newString();intcontsemicolon=0;while((linha=br.readLine().substring(0,72))!=null&&contsemicolon<2){if(linha.toLowerCase().indexOf(oQueProcuro.toLowerCase())>0){contsemicolon++;}if(linha.toLowerCase().indexOf(oQueProcuro.toLowerCase())>-1){EntidadeWin+=linha.substring(0,72)+"\n";sb.append('\n');mapaWindow.put(oQueProcuro,EntidadeWin);}}Set<String>listaEncontrados=mapaWindow.keySet();Iterator<String>it=listaEncontrados.iterator();while(it.hasNext()){StringchaveMapa=it.next();System.out.println(mapaWindow.get(chaveMapa));}}catch(HeadlessExceptione){e.printStackTrace();}catch(FileNotFoundExceptione){e.printStackTrace();}catch(IOExceptione){e.printStackTrace();}finally{if(br!=null){try{br.close();}catch(IOExceptione){e.printStackTrace();}}}}}
Porém Só consigo imprimr as linhas em que a string buscada é encontrada. Algué consegue me ajudar?
Primeiro identifique o local que está com sua string (window).
Depois que identificar esta linha, comece a ler o arquivo procurando o segundo “;”.
No seu código em nenhum momento você procura um “;” sequer!
marcioluiz
Ok. MAs vc teria alguma dica pra me dar sobre como recuperar mais de uma linha de umarquivo sendo lido?
Vlw!
Grato pela resposta.
robertol
Bom, você não precisa saber como recuperar mais de uma linha por vez.
Mas continuando o que eu estava falando, você deve identificar primeiro onde está o termo procurado. A partir daí, procurar os dois ; que você precisa.
Vou escrever um algoritmo sem preocupações com sintaxe. Aí você verifica se funciona para você, ok?
Olha só Onde Cheguei: fora essa classe, fiz outra para tratar excessão.
publicclassComsWindowReader{publicstaticvoidmain(String[]args)throwsComsWindowReaderException{// Lê do teclado o nome da windowScannerscanner=newScanner(System.in);System.out.println("Digite o nome da window: ");// leitura da windowStringdadoProcurado=scanner.next();//args[0] substituir depois - LembreteSystem.out.println("Listagem da window: "+" "+dadoProcurado+" ");FileReaderfr=null;BufferedReaderbr=null;// endereco do arquivofinalStringCAMINHO_ARQUIVO="c:"+File.separator+"unifiles"+File.separator+"Coms-Window.txt";try{// Declaracao do TreeMap que armazena a window e suas// características.TreeMap<String,String>mapaWindow=newTreeMap<String,String>();// Referência do arquivo a ser lido.Filef=newFile(CAMINHO_ARQUIVO);// objetos de leitura do arquivo.fr=newFileReader(f);br=newBufferedReader(fr);// linha corrente do arquivoStringlinha;// guarda um buffer com os dados da windowStringBufferbufferDadosWindow=newStringBuffer();// controla o numero de semiColons encontrados para cada window.intnumeroSemiColon=0;// enquanto esse flag for true, concatena as linhsa do arquivo para// cada window.booleanencontrouItemProcurado=false;intnumeroLinha=1;while((linha=br.readLine())!=null){try{linha=linha.substring(0,72);}catch(Exceptione){thrownewComsWindowReaderException("Formato de arquivo inválido. "+"Não foi possível separar a linha "+numeroLinha+"do arquivo com 72 caracteres.");}// verifica se existe na linha corrente a window desejadaif(linha.toLowerCase().indexOf(dadoProcurado.toLowerCase())>0){encontrouItemProcurado=true;}// controla o numero de semicolons que definem quais linhas// compôem os dados da window.if(linha.indexOf(";")!=-1){numeroSemiColon++;}/* * Controla se a linha lida faz parte da window passada por * parâmetro. Se não for possível quebrar a linha em 72 * caracteres, entende-se que o arquivo está mal formado e uma * exceção é lançada. */if(encontrouItemProcurado==true){try{linha=linha.substring(0,72);}catch(Exceptione){thrownewComsWindowReaderException("Formato de arquivo inválido. "+"Não foi possível separar a linha "+numeroLinha+"do arquivo com 72 caracteres.");}bufferDadosWindow.append(linha).append("\n");mapaWindow.put(dadoProcurado,bufferDadosWindow.toString());}/* * quando encontra o segundo semicolon, significa que os dados * da window já acabaram. Sendo assim, seta o item procurado * para false e seta o flag numeroSemiColon para 0 para evitar * cópia de linhas indesejadas */if(numeroSemiColon>=2){encontrouItemProcurado=false;numeroSemiColon=0;}// incrementa o número de linhas lidas no arquivonumeroLinha++;}Set<String>listaEncontrados=mapaWindow.keySet();Iterator<String>it=listaEncontrados.iterator();// impressaowhile(it.hasNext()){StringchaveMapa=it.next();System.out.println(mapaWindow.get(chaveMapa));}}catch(FileNotFoundExceptione){thrownewComsWindowReaderException("Erro ao tentar abrir o arquivo. Arquivo inexistente. Detalhes do erro. "+e.getMessage());}catch(IOExceptione){thrownewComsWindowReaderException("Erro na manipulação de arquivo . Detalhes do erro. "+e.getMessage());}finally{if(br!=null){try{br.close();}catch(IOExceptione){thrownewComsWindowReaderException("Erro ao tentar fechar arquivo. Detalhes do erro. "+e.getMessage());}}}}}
robertol
Você testou este código?
Pelo que entendi do seu problema, a contagem das ocorrências do “;” deve ser feita apenas depois de localizada a ocorrência da window passada, correto?
Deste modo, a verificação se o ponto e vírgula existe na linha deveria ser feito só depois de confirmado que a window foi encontrada.
Teste alguns casos:
1 - window = firefox
exemplo de texto:
teste;firefox
a janela;;
2 - window = eclipse
exemplo de texto
eclipse é uma IDE de desenvolvimento;
qualquer coisa;
qualquer coisa 2;
eclipse novamente;
oi;
qualquer coisa;
marcioluiz
POis é vc pegou no "X"da questão.
Agora a minha dúvida é a seguinte eu gostaria que quando fosse encontrada o segundo “;”. A inclusão de linha parasse.
E que inclusive a última linha, ou seja a linha contendo o 2º “;” não fosse incluída.
Vc tem alguma sugestão?
Vlw!
robertol
Bom, vc pode colocar esta condição na cláusula do while ou qdo atingir o segundo ; você dar um break dentro do while. Isto forçaria que o loop parasse, não adicionando mais nenhum conteúdo.
Se vc não quer incluir a última linha, é só vc dar o break antes da inclusão… por exemplo: