java.nio.fichier.Les fichiers.supprimer Path(chemin d'accès) - échec occasionnel récursive de supprimer le répertoire à l'aide de SimpleFileVisitor
D'essayer de résoudre un occasionnel java.nio.file.DirectoryNotEmptyException
dans une suppression récursive de la méthode de prise de Supprimer les répertoires de manière récursive en Java
Code (crédit à @TrevorRobinson) :
static void removeRecursive(Path path) throws IOException {
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
logger.warn("Deleting " + file.getFileName());
Files.delete(file);
logger.warn("DELETED " + file.getFileName());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
//try to delete the file anyway, even if its attributes could
//not be read, since delete-only access is theoretically possible
//I NEVER SEE THIS
logger.warn("Delete file " + file + " failed", exc);
try {
Files.delete(file);
} catch (IOException e) {
logger.warn(
"Delete file " + file + " failed again", exc);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc)
throws IOException {
if (exc == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
//directory iteration failed; propagate exception
throw exc;
}
});
}
Appel:
try {
removeRecursive(Paths.get(unzipDirPath));
} catch (IOException e) {
String msg = "Failed to delete folder " + unzipDirPath;
if (e instanceof java.nio.file.DirectoryNotEmptyException) {
msg += ". Still contains : ";
final File[] listFiles = Paths.get(unzipDirPath).toFile().listFiles();
if (listFiles != null) for (File file : listFiles) {
msg += file.getAbsolutePath() + "\n";
}
}
log.error(msg, e);
}
Imprime (une fois dans 20/40 itérations):
22:03:34.190 [http-bio-8080-exec-47] WARN g.u.d.m.server.servlets.Controller$1 - Deleting batt
22:03:34.192 [http-bio-8080-exec-47] WARN g.u.d.m.server.servlets.Controller$1 - DELETED batt
22:03:34.192 [http-bio-8080-exec-47] WARN g.u.d.m.server.servlets.Controller$1 - Deleting wifi
22:03:34.193 [http-bio-8080-exec-47] WARN g.u.d.m.server.servlets.Controller$1 - DELETED wifi
22:03:34.196 [http-bio-8080-exec-47] ERROR g.u.d.m.s.s.DataCollectionServlet - Failed to delete folder C:\yada\. Still contains : C:\yada\dir\wifi
java.nio.file.DirectoryNotEmptyException: C:\yada\dir
at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:265) ~[na:1.7.0_45]
at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103) ~[na:1.7.0_45]
at java.nio.file.Files.delete(Files.java:1077) ~[na:1.7.0_45]
at gr.uoa.di.monitoring.server.servlets.Controller$1.postVisitDirectory(Controller.java:128) ~[Controller$1.class:na]
at gr.uoa.di.monitoring.server.servlets.Controller$1.postVisitDirectory(Controller.java:1) ~[Controller$1.class:na]
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:224) ~[na:1.7.0_45]
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:199) ~[na:1.7.0_45]
at java.nio.file.FileTreeWalker.walk(FileTreeWalker.java:69) ~[na:1.7.0_45]
at java.nio.file.Files.walkFileTree(Files.java:2600) ~[na:1.7.0_45]
at java.nio.file.Files.walkFileTree(Files.java:2633) ~[na:1.7.0_45]
at gr.uoa.di.monitoring.server.servlets.Controller.removeRecursive(Controller.java:96) ~[Controller.class:na]
at gr.uoa.di.monitoring.server.servlets.DataCollectionServlet.doPost(DataCollectionServlet.java:153) ~[DataCollectionServlet.class:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) [servlet-api.jar:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) [servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) [catalina.jar:7.0.32]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) [catalina.jar:7.0.32]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) [catalina.jar:7.0.32]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) [catalina.jar:7.0.32]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) [catalina.jar:7.0.32]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) [catalina.jar:7.0.32]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) [catalina.jar:7.0.32]
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) [catalina.jar:7.0.32]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) [catalina.jar:7.0.32]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) [catalina.jar:7.0.32]
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) [tomcat-coyote.jar:7.0.32]
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) [tomcat-coyote.jar:7.0.32]
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) [tomcat-coyote.jar:7.0.32]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_45]
at java.lang.Thread.run(Thread.java:744) [na:1.7.0_45]
Avis que wifi
est indiqué comme supprimé - ce qui est encore plus bizarre, c'est que j'ai parfois l' :
Pas réussi à supprimer le dossier C:\yada. Contient encore : C:\yada\dir
java.nio.fichier.DirectoryNotEmptyException: C:\yada\dir
J'ai tendance vers la conclusion que, parfois, la suppression prend trop de temps - en d'autres termes, le problème est que java.nio.file.Files.delete(Path path)
ne bloque pas (donc C:\yada\dir encore contient des fichiers lorsque le temps vient, qui, parfois, sont effacées par le temps, j'stat). Alors, comment suis-je pour contourner ce problème ?
Aussi : est java.nio.file.Files.delete(Path path)
nécessaires à jeter ? Le docs état :
Sur certains systèmes d'exploitation, il peut ne pas être possible de supprimer un fichier lorsqu'il est ouvert et en cours d'utilisation par cette machine virtuelle Java ou d'autres programmes.
Ne semble pas exiger la levée d'une exception dans ce cas. Est java.nio.file.Files.delete(Path path)
nécessaire de jeter ?
C'est pour java.io.Fichier.delete() qui retourne un booléen !
Elle met également en différentes exceptions fondées sur le problème: FileNotFoundException, SecurityException, etc. Vous pouvez attraper ces exceptions et de répondre à chacune de façon appropriée.
Je suis en demandant au sujet d'une autre méthode.......
Les deux méthodes de faire la même chose: docs.oracle.com/javase/7/docs/api/java/nio/file/...
OriginalL'auteur Mr_and_Mrs_D | 2013-11-12
Vous devez vous connecter pour publier un commentaire.
J'ai eu le même problème et il s'est avéré que le problème a été causé par un unclosed annuaire flux de fichier quelque part ailleurs dans le code pour le même répertoire que je a été de supprimer des trucs de. Le flux de l'objet renvoyé par:
doit être fermé, alors assurez-vous d'utiliser le try-with-resources construire dans votre code si vous utilisez cette méthode.
Donc je ne pense pas que c'est que la suppression prend trop de temps, j'ai essayé d'attendre avant de réessayer répertoire suppression sans un peu de chance. Il est plus que probable que votre propre programme de cette ressource verrouillée. Le résultat est que la suppression de l'appeler sur lui il ne peut pas se terminer bien qu'il retourne avec succès (il ressemble à Windows finira par supprimer le fichier une fois que votre propre programme permet de se libérer) mais ensuite, bien sûr, le répertoire ne peut pas être supprimé, car c'est en effet pas encore vide.
C'est stupide, que les opérations de terminal sur un Flux<T> ne pas appeler
close()
sur elle. Utilisation de try-with-resources sur mon précédentFiles.list(path)
résolu ce même problème pour moi.Merci, c'est facile à oublier. Après 30 minutes de débogage, il s'est avéré ce fut la cause.
OriginalL'auteur user3485962
Je sais que c'est un très vieux thread mais j'ai eu le même problème et il m'a fallu un certain temps pour le faire réparer.
Je pense que ce mauvais comportement est causé par un problème de synchronisation (qui ressemble à ce qui se passe sur Windows seulement), donc j'ai mis une pause dans le postVisitDirectory méthode. Qui a travaillé et c'est ce que j'ai finalement venu avec:
Une méthode qui ne le supprimer sans jeter la DirectoryNotEmptyException:
et de son utilisation dans une boucle:
Andy
OriginalL'auteur andy
Vous pourriez stocker temporairement le nom du fichier que vous êtes en train de l'itération dans une variable et d'effectuer un try-catch sur
DirectoryNotEmptyException
. Lorsque cette exception se produit, l'attraper et lancer votre propre exception qui spécifie le fichier.Obtenir le nom de fichier peut être fait avec
e.getMessage();
Je suppose
Files.delete()
continue d'effacer les fichiers dans un répertoire lorsqu'il rencontre un fichier qui ne peut pas être supprimé. Si c'est le cas, ma méthode fonctionne toujours: il suffit de retourner une liste de tous les fichiers du répertoire à la place du nom de fichier du répertoire. Il ne doit contenir que des fichiers qui ne peuvent pas être supprimés et vous avez toujours votre solution.file
vous êtes de rattrapage est le répertoire n'est pas vide - la méthode récursive devez supprimer tous les fichiers dans répertoire et c'est l'échec et je veux voir ce qui fichier n'a pas pu être supprimé et pourquoi !voir modifier.
Je veux savoir pourquoi comme l'indique clairement la question - j'ai déjà une liste - voir mon edit. Gosh, je ne suis même pas sûr de supprimer ne pas jeter de l' - les docs sont pas clair
Vous souhaiterez peut-être plus poli avec les gens qui essaient de vous aider. Le
DirectoryNotEmptyException
est jeté parce que vous tentez de supprimer un dossier qui contient des fichiers. C'est programmé d'une façon qu'il ignore les fichiers qu'il ne peut pas supprimer: pas d'événements sont déclenchés et aucune exception n'est levée. Si vous voulez vérifier la cause, vous pouvez utiliserFile.canRead()
,file.CanWrite()
etFile.canExecute()
pour voir si c'est un problème d'autorisation et/ou si elle est en cours d'utilisation. Ceux-ci devraient être les seules raisons pour lesquelles un fichier ne peut pas être supprimé.Veuillez noter que vous avez été de ne pas répondre à la question - je le trouver pas très poli à ne pas lire une question avec soin (vous pouvez suivre les révisions à voir, par exemple, que je dis que je suis en mesure d'afficher la liste des fichiers depuis éditer 0 : stackoverflow.com/revisions/19935624/1- et vous accompagner et répondre à moi que je peux obtenir la liste des fichiers, complètement à côté du sujet !). Exactement où ai-je été impoli ? Gosh est allé à l' (pas clair) docs. De toute façon revenir à la question : "C'est programmé d'une façon qu'il ignore les fichiers qu'il ne peut pas supprimer" - qui est ce ?
OriginalL'auteur Jeroen Vannevel
Une expansion sur mon commentaire ci-dessus.
Lorsque Java est un problème de faire quelque chose, il jette un Exception. Des Exceptions, comme tous les autres types, qui peuvent être héritées d'. L'API de spécifier qui a vérifié les exceptions de chaque méthode de lancers. Les méthodes de
java.io
etjava.nio
généralement jeterIOException
ou d'un de ses enfants. Si vous souhaitez créer une méthode qui va vous dire pourquoi l'opération de fichier, dans ce cas, la suppression, a échoué, vous pouvez faire quelque chose comme ceci:Vous pouvez modifier la réponse du programme que vous avez besoin, mais cela devrait vous donner l'idée générale.
Par curiosité, tu comprends la différence entre les rendements et les jette?
OriginalL'auteur crownjewel82