2012-09-07 4 views
6

Quando una directory controllata da WatchService viene eliminata, la directory principale non riflette immediatamente l'eliminazione nel suo metodo listFiles del file e non può essere eliminata. Fino a quando l'intero servizio è esplicitamente stopped le conseguenze per il genitore sembrano essere:Il servizio di visualizzazione Java sembra ricreare i file cancellati. Cosa sta succedendo?

  1. Il recommended recursive solution per l'eliminazione di una directory fallimento non vuota.
  2. deleteOnExit non eseguito alla terminazione normale
  3. Chiamate a delete restituisce false e non ha alcun effetto sul file system.

Per dimostrare questo codice di prova:

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); 
    } 
    } 
} 

pronunciato la seguente output sulle finestre, che corrisponde con testDir non essere eliminati nel file system.

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 

Se metto un punto di interruzione dopo l'eliminazione subDir posso vedere che è stata effettivamente cancellata sul filesystem. La ripresa dal punto di interruzione fa sì che l'ultima cancellazione sia superata, suggerendo che questo potrebbe essere un problema con la visibilità delle modifiche apportate dal thread del servizio di controllo. Qualcuno sa cosa sta succedendo qui, e se è un bug? Quello che sto provando a fare è eliminare le directory che vengono monitorate senza arrestare il monitoraggio su altre directory, dato che non sembra essere un metodo di percorso di annullamento della registrazione fornito dall'API quali sono altri modi standard Java per realizzare questo?

+0

Mi chiedo se questo è un problema di Windows – Pyrolistical

+1

Stesso comportamento qui. Aggiungere un 'Thread.sleep (100);' in main prima di chiamare 'delete (new File (testDirName));' risolve il problema - strano ... – assylias

risposta

7

possibilmente correlati:

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

Il WatchService ha un handle aperto per ogni directory guardato. Se una directory di controllo viene eliminata, WatchService chiude l'handle in modo che la voce della directory possa essere rimossa dalla directory padre. Sorge un problema per le utilità e l'applicazione che si aspettano di essere in grado di eliminare immediatamente la directory padre in quanto potrebbero richiedere alcuni millisecondi affinché il servizio di controllo ottenga la notifica e chiuda l'handle. Se durante questo periodo lo strumento tenta di eliminare la directory padre, fallirà. Al momento non abbiamo una soluzione a questo problema.

+0

+1 Sembra essere esattamente questo. – assylias

Problemi correlati