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:
package buscacarteiras;
import java.awt.HeadlessException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.Scanner;
public class Script_Listagem {
public static void main(String[] args) {
// Lê do teclado o nome da window
Scanner dados = new Scanner(System.in);
System.out.println("Digite o nome da window: ");
// leitura da window
String window = dados.next();
System.out.println("Listagem da window: " + window);
FileReader fr = null;
BufferedReader br = null;
StringBuffer sb = null;
// endereco do arquivo
String CAM_AQ_WD = "c:/" + "unifiles/" + "Coms-Window.txt";
try {
// sring que armazena a window
String oQueProcuro = window;
// Declaracao do TreeMap que armazena a window
TreeMap<String, String> mapaWindow = new TreeMap<String, String>();
// leitura do arquivo window
File f = new File(CAM_AQ_WD);
fr = new FileReader(f);
br = new BufferedReader(fr);
sb = new StringBuffer(5000);
String linha = "";
String EntidadeWin = new String();
int contsemicolon = 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()) {
String chaveMapa = it.next();
System.out.println(mapaWindow.get(chaveMapa));
}
} catch (HeadlessException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Porém Só consigo imprimr as linhas em que a string buscada é encontrada. Algué consegue me ajudar?
Vlw!
Você deveria tratar seus problemas por partes!
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!
Ok. MAs vc teria alguma dica pra me dar sobre como recuperar mais de uma linha de umarquivo sendo lido?
Vlw!
Grato pela resposta.
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?
boolean naoEncontrado = true;
StringBuffer texto = new StringBuffer();
String linha;
int contsemicolon = 0;
// Procura a primeira ocorrência do texto procurado
while (naoEncontrado) {
linha = br.readLine();
if (linha == null) break;
if (linha.toLowerCase().indexOf(oQueProcuro.toLowerCase()) > -1 ) {
sb.append(linha);
}
}
// Procura duas ocorrências do ;
// É importante checar se a linha lida anteriormente possui o ;
if (sb.toString().indexOf(";") > -1) contsemicolon++;
while(contsemicolon < 2) {
// aqui você vai ler do arquivo e verificar se existe o ;
// não esqueça de adicionar o texto ao sb independente de possuir ou não o ;, ok?
linha = br.readLine();
if (linha == null) break;
sb.append(linha);
if (linha.toLowerCase().indexOf(";") > -1 ) {
contsemicolon++;
}
}
Vlw demais Amigo.
Olha só Onde Cheguei: fora essa classe, fiz outra para tratar excessão.
public class ComsWindowReader {
public static void main(String[] args) throws ComsWindowReaderException {
// Lê do teclado o nome da window
Scanner scanner = new Scanner(System.in);
System.out.println("Digite o nome da window: ");
// leitura da window
String dadoProcurado = scanner.next(); //args[0] substituir depois - Lembrete
System.out.println("Listagem da window: " + " "+ dadoProcurado +" ");
FileReader fr = null;
BufferedReader br = null;
// endereco do arquivo
final String CAMINHO_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 = new TreeMap<String, String>();
// Referência do arquivo a ser lido.
File f = new File(CAMINHO_ARQUIVO);
// objetos de leitura do arquivo.
fr = new FileReader(f);
br = new BufferedReader(fr);
// linha corrente do arquivo
String linha;
// guarda um buffer com os dados da window
StringBuffer bufferDadosWindow = new StringBuffer();
// controla o numero de semiColons encontrados para cada window.
int numeroSemiColon = 0;
// enquanto esse flag for true, concatena as linhsa do arquivo para
// cada window.
boolean encontrouItemProcurado = false;
int numeroLinha = 1;
while ((linha = br.readLine()) != null) {
try {
linha = linha.substring(0, 72);
} catch (Exception e) {
throw new ComsWindowReaderException(
"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 desejada
if (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 (Exception e) {
throw new ComsWindowReaderException(
"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 arquivo
numeroLinha++;
}
Set<String> listaEncontrados = mapaWindow.keySet();
Iterator<String> it = listaEncontrados.iterator();
// impressao
while (it.hasNext()) {
String chaveMapa = it.next();
System.out.println(mapaWindow.get(chaveMapa));
}
} catch (FileNotFoundException e) {
throw new ComsWindowReaderException(
"Erro ao tentar abrir o arquivo. Arquivo inexistente. Detalhes do erro. "
+ e.getMessage());
} catch (IOException e) {
throw new ComsWindowReaderException(
"Erro na manipulação de arquivo . Detalhes do erro. "
+ e.getMessage());
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
throw new ComsWindowReaderException(
"Erro ao tentar fechar arquivo. Detalhes do erro. "
+ e.getMessage());
}
}
}
}
}
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;
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!
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:
if (linha.indexOf(";") > -1) {
numeroSemiColon ++;
if (numeroSemiColon > 1) {
break;
}
}
sb.append(linha);
Observe que este código estaria dentro do while após achar o valor procurado…
Entendeu o que eu quis dizer?
Entendi sim.
Valer demais hein robertol!
Vou testar e te falo.