J'essaie de supprimer un fichier, après y avoir écrit quelque chose, avec FileOutputStream
. Voici le code que j'utilise pour écrire:
private void writeContent(File file, String fileContent) {
FileOutputStream to;
try {
to = new FileOutputStream(file);
to.write(fileContent.getBytes());
to.flush();
to.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Comme on le voit, je vide et ferme le flux, mais lorsque j'essaye de supprimer, file.delete()
renvoie false.
J'ai vérifié avant la suppression pour voir si le fichier existe et: file.exists()
, file.canRead()
, file.canWrite()
, file.canExecute()
tout retour vrai. Juste après avoir appelé ces méthodes, j'essaye file.delete()
et renvoie false.
Y a-t-il quelque chose que j'ai fait de mal?
java
file
fileoutputstream
Jenny Smith
la source
la source
Réponses:
Un autre bogue en Java. Je les trouve rarement, seulement ma deuxième en 10 ans de carrière. C'est ma solution, comme d'autres l'ont mentionné. Je n'ai jamais utilisé
System.gc()
. Mais ici, dans mon cas, c'est absolument crucial. Bizarre? OUI!la source
new File(path)
), j'ai rencontré le même problème et l'ajoutSystem.gc()
avant quedelete()
cela fonctionne!System.gc
astuce fonctionne à chaque fois.System.gc(); result = file.delete(); if (!result){ Thread.sleep(100); System.gc(); result = file.delete(); }
C'était assez étrange le truc qui a fonctionné. Le problème, c'est que lorsque j'ai lu le contenu du fichier, je l'ai utilisé
BufferedReader
. Après lecture, j'ai fermé le tampon.Pendant ce temps, j'ai changé et maintenant je lis le contenu en utilisant
FileInputStream
. Aussi après avoir fini de lire, je ferme le flux. Et maintenant ça marche.Le problème est que je n'ai pas d'explication à cela.
Je ne sais pas
BufferedReader
etFileOutputStream
être incompatible.la source
finalize()
pour assurer le nettoyage? Ou peut-être ensembleto = null
? Voir Forcer la finalisation et la récupération de place .J'ai essayé cette chose simple et cela semble fonctionner.
Ça marche pour moi.
Si cela ne fonctionne pas, essayez d'exécuter votre application Java avec sudo sous Linux et en tant qu'administrateur sous Windows. Juste pour être sûr que Java a le droit de modifier les propriétés du fichier.
la source
Avant d'essayer de supprimer / renommer un fichier, vous devez vous assurer que tous les lecteurs ou rédacteurs (par exemple:
BufferedReader
/InputStreamReader
/BufferedWriter
) sont correctement fermés.Lorsque vous essayez de lire / écrire vos données depuis / vers un fichier, le fichier est conservé par le processus et n'est pas libéré tant que l'exécution du programme n'est pas terminée. Si vous souhaitez effectuer les opérations de suppression / changement de nom avant la fin du programme, vous devez utiliser la
close()
méthode fournie avec lesjava.io.*
classes.la source
Comme Jon Skeet l'a commenté, vous devez fermer votre fichier dans le bloc finally {...}, pour vous assurer qu'il est toujours fermé. Et, au lieu d'avaler les exceptions avec e.printStackTrace, n'attrapez simplement pas et n'ajoutez pas l'exception à la signature de la méthode. Si vous ne pouvez pas pour une raison quelconque, faites au moins ceci:
Maintenant, question numéro 2:
Et si vous faites ceci:
Seriez-vous capable de supprimer le fichier?
De plus, les fichiers sont vidés lorsqu'ils sont fermés. J'utilise IOUtils.closeQuietly (...), donc j'utilise la méthode flush pour m'assurer que le contenu du fichier est là avant d'essayer de le fermer (IOUtils.closeQuietly ne lève pas d'exceptions). Quelque chose comme ça:
Je sais donc que le contenu du fichier s'y trouve. Comme il m'importe généralement que le contenu du fichier soit écrit et non si le fichier peut être fermé ou non, peu importe si le fichier a été fermé ou non. Dans votre cas, comme cela compte, je recommanderais de fermer le dossier vous-même et de traiter les exceptions en conséquence.
la source
Il n'y a aucune raison pour laquelle vous ne devriez pas pouvoir supprimer ce fichier. Je chercherais à voir qui détient ce dossier. Sous unix / linux, vous pouvez utiliser l'utilitaire lsof pour vérifier quel processus a un verrou sur le fichier. Dans Windows, vous pouvez utiliser l'explorateur de processus.
pour lsof, c'est aussi simple que de dire:
pour l'explorateur de processus, vous pouvez utiliser le menu de recherche et entrer le nom du fichier pour vous montrer la poignée qui vous dirigera vers le processus de verrouillage du fichier.
voici un code qui fait ce que je pense que vous devez faire:
Cela fonctionne bien sur OS X. Je ne l'ai pas testé sur Windows mais je pense que cela devrait également fonctionner sur Windows. J'admettrai également avoir vu un comportement inattendu sur la gestion des fichiers Windows Wrt.
la source
Si vous travaillez dans Eclipse IDE, cela peut signifier que vous n'avez pas fermé le fichier lors du lancement précédent de l'application. Lorsque j'ai eu le même message d'erreur en essayant de supprimer un fichier, c'était la raison. Il semble qu'Eclipse IDE ne ferme pas tous les fichiers après l'arrêt d'une application.
la source
J'espère que cela aidera. Je suis tombé sur un problème similaire où je ne pouvais pas supprimer mon fichier après que mon code java ait fait une copie du contenu dans l'autre dossier. Après une recherche approfondie sur Google, j'ai explicitement déclaré toutes les variables liées aux opérations de fichier et appelé la méthode close () de chaque objet d'opération de fichier, et les ai définies sur NULL. Ensuite, il y a une fonction appelée System.gc (), qui effacera le mappage des entrées / sorties de fichiers (je ne suis pas sûr, je dis juste ce qui est donné sur les sites Web).
Voici mon exemple de code:
la source
la réponse est que lorsque vous chargez le fichier, vous devez appliquer la méthode "close", dans n'importe quelle ligne de code, fonctionne pour moi
la source
Il y avait un problème une fois dans ruby où les fichiers dans Windows avaient besoin d'un "fsync" pour pouvoir réellement se retourner et relire le fichier après l'avoir écrit et fermé. Peut-être que c'est une manifestation similaire (et si c'est le cas, je pense qu'un bug de Windows, vraiment).
la source
Aucune des solutions énumérées ici n'a fonctionné dans ma situation. Ma solution était d'utiliser une boucle while, en essayant de supprimer le fichier, avec une limite de 5 secondes (configurable) pour la sécurité.
L'utilisation de la boucle ci-dessus a fonctionné sans avoir à faire de ramasse-miettes manuel ou à définir le flux sur null, etc.
la source
Le problème peut être que le fichier est toujours considéré comme ouvert et verrouillé par un programme; ou peut-être est-ce un composant de votre programme dans lequel il a été ouvert, vous devez donc vous assurer d'utiliser la
dispose()
méthode pour résoudre ce problème. c'est à direJFrame frame; .... frame.dispose();
la source
Vous devez fermer tous les flux ou utiliser le bloc try-with-resource
la source
si file.delete () envoie false, dans la plupart des cas, votre handle de Bufferedreader ne sera pas fermé. Juste fermer et cela semble fonctionner pour moi normalement.
la source
J'ai eu le même problème sous Windows. J'avais l'habitude de lire le fichier en scala ligne par ligne avec
Maintenant je le lis dans son ensemble avec
qui ferme le fichier correctement après la lecture et maintenant
travaux.
la source
Redémarrez votre IDE et exécutez à nouveau votre code, ce n'est qu'un truc pour moi après une heure de lutte.
Voici mon code:
Production:
Supprimer
la source
Un autre cas de coin où cela pourrait se produire: si vous lisez / écrivez un fichier JAR via un
URL
et plus tard, essayez de supprimer le même fichier dans la même session JVM.La raison en est que la logique de gestion des fichiers JAR internes de Java a tendance à mettre en cache les
JarFile
entrées:Et chacun
JarFile
(plutôt, laZipFile
structure sous-jacente ) détiendrait une poignée pour le fichier, dès le moment de la construction jusqu'àclose()
son invocation:Il y a une bonne explication sur ce problème NetBeans .
Apparemment, il existe deux façons de "résoudre" ce problème:
Vous pouvez désactiver la mise en cache du fichier JAR - pour la session actuelle
URLConnection
ou pour tous les futursURLConnection
(globalement) dans la session JVM actuelle:[AVERTISSEMENT DE HACK!] Vous pouvez purger manuellement le
JarFile
du cache lorsque vous avez terminé. Le gestionnaire de cachesun.net.www.protocol.jar.JarFileFactory
est privé de package, mais une certaine magie de réflexion peut faire le travail pour vous:Remarque: tout ceci est basé sur la base de code Java 8 (
1.8.0_144
); ils peuvent ne pas fonctionner avec d'autres versions / versions ultérieures.la source