Hola.
Nunca he usado la clase Scanner para leer ficheros, siempre he usado la calse BufferedReader.
Sin embargo, la mecánica viene a ser la misma.
Vamos por partes.
1.Usas un JOptionPane para que el usuario introduzca el dato a buscar. ESto significa que ya no necesitas usar el Scanner para leer el dato a buscar, te lo proporciona directamente el JOptionPane si recoges el String que te está devolviendo.
Así que todo eso lo puedes hacer en una única linea. Te tacho las que no necesitas:
Scanner lector;
lector = new Scanner(System.in);
String datoAbuscar = JOptionPane.showInputDialog("Dato a buscar:");
datoAbuscar = lector.nextLine();
2.SIEMPRE, pero SIEMPRE..... cuando queremos leer/escribir ficheros, estaremos obligados a controlar posibles excepciones (errores) que puedan ocurrir al acceder a estos ficheros.
No es opcional, Java nos obliga. Y además, es lo deseable.
Esto significa que la creacion del objeto Scanner para leer fichero las lectura a realizar, han de ir dentro de un
try {}.....
seguido de un
catch(){} donde le diremos que ha de hacer en caso de que ocurrar el posible error de no poder acceder al archivo, por ejemplo mostrar una ventana explicando el error.
Te destaco en verde el codigo que va dentro del try{} y en rojo el catch
try {
Scanner lector = new Scanner(file);
while (lector.hasNextLine()) {
String datoBuscado = lector.nextLine();
if (datoBuscado.startsWith(datoAbuscar)) {
JOptionPane.showMessageDialog(null,"Dato buscado\n" + datoBuscado);
}
while(datoBuscado!=("|"));
}
} catch (FileNotFoundException e) {
JOptionPane.showMessageDialog(null, "No se ha encontrado el fichero " + file.getAbsolutePath());
e.printStackTrace();//Muestra por consola la "traza" del error
}
3.Centrémonos en el código que hay dentro del try{}
Ahora mismo, con el código que pusiste, prácticamente ya estaríamos funcionando correctamente.
Solo comentar dos cosas:
- La linea:
while(datoBuscado!=("|"));
No sirve para nada, excepto para provocar un bucle de duración infinito y bloquear el programa para toda la eternidad.
Elimínala. No se qué es lo que pretendías hacer en ese punto del código, pero sea lo que sea, esa línea no te sirve, ya que solo consigue bloquear el programa, ya que datoBuscado SIEMPRE será distinto de "|", excepto que el usuario haya indicado que quiere buscar ese caracter.
-Por último.
Si usamos los métodos .hasNextLine() y nextLine(), estaríamos leyendo lineas completas del archivo de texto.
Además estamos usando el método .startsWith() que nos dirá si la linea tiene al principio el mismo dato que estamos buscando.
Puede que eso sea lo que queramos. Pero tal vez queramos ser más precisos en las lecturas y en lugar de leer lineas enteras, queramos leer palabra por palabra.
Supon que el archivo txt donde estamos buscando, contiene este texto:
rojo azul verde amarillo
barcelona madrid granada
perro gato marmota
Con los métodos que estamos usando ahora mismo. Podríamos encontrar los datos "rojo", "barcelona" y "perro". Porque son los datos con los que comienzan las lineas y es lo que encontrará el método .startsWith()
Pero no seríamos capaces de encontrar el resto de datos: "azul", "granada", "marmota", etc... como no están al principio de la linea, el método .startsWith() no sabrá encontrarlos.
Esto podemos solucionarlo, usando el método contains(), en lugar de .startsWith()
Sustituimos lo tachado:
if (datoBuscado.startsWith(datoAbuscar)) {
JOptionPane.showMessageDialog(null,"Dato buscado\n" + datoBuscado);
}
Por lo marcado en verde:
if (datoBuscado.contains(datoAbuscar)) {
JOptionPane.showMessageDialog(null,"Dato buscado\n" + datoBuscado);
}
Ahora sí, ya sí podríamos encontrar cualquiera de esos datos. Y ya estamos cumpliendo con lo que pide el ejercicio. Todo resuelto
Peeeero..., aún podemos ser más precisos.
Ahora mismo estamos leyendo lineas enteras porque usamos los métodos .hasNextLine() y nextLine()
Usemos este texto:
rojo azul azul azul
barcelona madrid granada
perro gato marmota
Supongamos que queremos que nuestro programa lanze un aviso cada vez que encuentra el dato que buscamos. Es decir, que si está repetido, nos lance un aviso para cada repetició.
Si buscamos la palabra "azul, ahora mismo nuestro programa se equivocaría, y diría que la palabra "azul" solo está 1 vez.
Porque lo que hace es leer la línea completa, comprueba si contiene la palabra "azul" -->(.contains("azul")), lanza un aviso y pasa a la siguiente linea, ignorando que la palabra "azul" esta repetida más veces en la primera línea.
Para evitar esto, podemos hacer que el Scanner, en lugar de lineas, que lea palabra por palabra con los métodos .hasNext() y next();
Quedaría así:
try {
Scanner lector = new Scanner(file);
while (lector.hasNext()) {
String datoBuscado = lector.next();
if (datoBuscado.contains(datoAbuscar)) {
JOptionPane.showMessageDialog(null,"Encontrado dato\n " + datoBuscado);
}
while(datoBuscado!=("|"));
}
Con esto ya debería funcionar, pruébalo y pregunta cualquier duda que puedas tener