2012-09-07 11 views
6

Cuando se elimina un directorio supervisado por WatchService, su directorio principal no refleja inmediatamente la eliminación en el método listFiles de su archivo y no se puede eliminar. Hasta que todo el servicio es explícitamente stopped las consecuencias para los padres parecen ser:Parece que el servicio de vigilancia de Java recrea los archivos eliminados. Que esta pasando?

  1. El recommended recursive solution para eliminar un defecto directorio no está vacío.
  2. deleteOnExit no está llevando a cabo en la terminación normal
  3. delete llamadas a devolver falso y no tiene efecto sobre el sistema de ficheros.

Para demostrar, este código de prueba:

import java.io.*; 
import java.nio.file.*; 

class DirectoryTester { 
    static WatchService watcher; 
    static { 
    try{watcher = FileSystems.getDefault().newWatchService();} 
    catch (IOException e) {e.printStackTrace();} 
    } 

    public static void main(String[] args) throws IOException { 
    String SEPARATE = System.getProperty("file.separator"); 
    String testDirName = System.getProperty("user.dir") + SEPARATE + "testDir"; 
    String subDirName = testDirName + SEPARATE + "subDir"; 
    String fileName = subDirName + SEPARATE +"aFile"; 
    create(fileName); 
    Paths.get(subDirName).register(watcher, StandardWatchEventKinds.ENTRY_DELETE); 
    delete(new File(testDirName)); 
    } 

    static void create(String nameOfFile) throws IOException { 
    new File(nameOfFile).getParentFile().mkdirs(); 
    Files.createFile(Paths.get(nameOfFile)); 
    System.out.println("Created " + nameOfFile); 
    }  

    static void delete(File toDelete) throws IOException { 
    if (toDelete.isDirectory()) 
     for (File c : toDelete.listFiles()) 
     delete(c); 
    int numContainedFiles = toDelete.listFiles() != null ? toDelete.listFiles().length : 0; 
    if (!toDelete.delete()) { 
     System.out.println("Failed to delete " + toDelete + " containing " + numContainedFiles); 
    } 
    else { 
     System.out.println("Deleted " + toDelete + " containing " + numContainedFiles); 
    } 
    } 
} 

da la siguiente salida en las ventanas, que se corresponde con testDir no ser eliminados en el sistema de archivos.

Created C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir\aFile 
Deleted C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir\aFile containing 0 
Deleted C:\Dropbox\CodeSpace\JavaTestbed\src\testDir\subDir containing 0 
Failed to delete C:\Dropbox\CodeSpace\JavaTestbed\src\testDir containing 1 

Si pongo un punto de interrupción después de la eliminación subDir puedo ver que en realidad ha sido eliminado del sistema de archivos. La reanudación desde el punto de interrupción provoca que la última eliminación suceda, lo que sugiere que esto podría ser un problema con la visibilidad de los cambios realizados por el hilo del servicio de vigilancia. ¿Alguien sabe lo que está pasando aquí, y si es un error? Lo que en realidad estoy tratando de hacer es eliminar los directorios que se monitorean sin detener el monitoreo en otros directorios, dado que no parece haber un método de ruta de acceso anulado por la API, ¿cuáles son otras formas Java estándar de lograr esto?

+0

Me pregunto si este es un problema solo de Windows – Pyrolistical

+1

Mismo comportamiento aquí. Agregar un 'Thread.sleep (100);' en main antes de llamar a 'delete (new File (testDirName));' resuelve el problema - raro ... – assylias

Respuesta

7

posiblemente relacionadas:

http://bugs.sun.com/view_bug.do?bug_id=6972833

El WatchService tiene un identificador abierto a cada directorio visto. Si se elimina un directorio de vigilancia, WatchService cierra el identificador para que la entrada del directorio se pueda eliminar del directorio principal. Se presenta un problema para las utilidades y la aplicación que esperan poder eliminar el directorio padre inmediatamente, ya que pueden pasar algunos milisegundos para que el servicio de vigilancia reciba la notificación y cierre el identificador. Si durante ese tiempo la herramienta intenta eliminar el directorio principal, fallará. No tenemos una solución para este problema en este momento.

+0

+1 Parece ser exactamente eso. – assylias

Cuestiones relacionadas