Tengo un programa de java que consta de un programa principal y multiples hilos que busca apariciones de palabras en los ficheros de texto de un directorio.
---> Programa Principal:
- Recibe como argumentos el directorio de trabajo donde se encuentran los ficheros .txt y la palabra que queremos buscar en ellos.
- Creará un fichero de texto vacío para recoger los resultados de la búsqueda y lanzará un hilo por cada fichero de txt.
- Finalmente, cuando todos los hilos han acabado, el programa principal escribirá por consola el contenido completo del fichero de resultados.
---> Hilo:
Es imprescindible que en el fichero de resultados no aparezcan mezcladas las apariciones de palabras en los distintos ficheros. Es decir, los hilos tienen que acceder de manera síncrona al archivo de log, y escribir de uno en uno en el mismo.
- Cada hilo buscará apariciones de la palabra en el fichero de texto que le asignemos.
- Con cada aparición, incorporará en el fichero de resultados:
- una línea con el nombre del fichero original y el número de línea en la que se encuentra dentro de dicho fichero
- una segunda línea con el contenido de la línea completa donde aparece la palabra buscada
Tengo el código entero generado para hacer todo lo que pide. Para el acceso síncrono al archivo de texto tengo creada una clase que es la encargada del manejo del txt en el que guardo el log.
Código:
Los hilos los lanzo en un bucle dentro del programa principal (la clase WordSearcher es la que es thread)public class FileAccess { private static FileWriter log; private static PrintWriter pw; public FileAccess(FileWriter log){ setLog(log); setPw(new PrintWriter(log)); } //Synchronized access public synchronized void printLine(String line){ getPw().println(line); getPw().close(); } }
Código:
Y luego los espero desde el programa principal también en bucle:private void launchThreads(){ numOfThreads = txtFiles.length; wordSearcherList = new WordSearcher[txtFiles.length]; for (int i=0; i<txtFiles.length;i++) { wordSearcherList[i] = new WordSearcher(getWord(), txtFiles[i], logPath, logFile, logFW, sem, numOfThreads, imDone); wordSearcherList[i].start(); } }
Código:
Estoy haciendo las pruebas con tres txt, todos con la palabra "servicios" y dos de ellos con la palabra "adios". Tanto con la primera palabra como con la segunda, parece que no espera a los hilos el programa principal. Unas veces me imprime las coincidencias en uno de los archivos sólo, otras en dos, otras en los tres... private void joinThreads(){ for (int i=0; i<wordSearcherList.length;i++){ try { wordSearcherList[i].join(); } catch (InterruptedException e) { System.err.println("Problems waiting threads"); } } }
He depurado y si que hace bien la búsqueda en cada hilo, y entra en aquellos en los que tiene que dejar constancia en el log para escribir, aunque no siempre lo modifica.
¿Cómo puedo hacer la escritura en el archivo de log de manera que el resultado final contenga lo que ha encontrado en todos los hilos?
Adjunto el trozo de código de WordSearcher en el que hago la escritura en el log:
Código:
Si necesitáis saber algo más del código decidme, y a ver si alguien sabe ayudarme a conseguir una sincronización de verdad. Creo que el fallo está en cuando accedo a escribir el log, puede que incluso en la creación del fichero.FileAccess fa = new FileAccess(logFW); fa.printLine(toPrint);
Gracias de antemano, un saludo