Ich versuche eine Datei zu löschen, nachdem ich etwas darin geschrieben habe, mit FileOutputStream
. Dies ist der Code, den ich zum Schreiben verwende:
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();
}
}
Wie zu sehen ist, spüle und schließe ich den Stream, aber wenn ich versuche zu löschen, wird file.delete()
false zurückgegeben.
Ich habe vor dem Löschen zu sehen , ob die Datei vorhanden ist , und: file.exists()
, file.canRead()
, file.canWrite()
, file.canExecute()
alle return true. Kurz nachdem ich diese Methoden aufgerufen habe, versuche ich, file.delete()
false zurückzugeben.
Gibt es etwas, was ich falsch gemacht habe?
java
file
fileoutputstream
Jenny Smith
quelle
quelle
Antworten:
Ein weiterer Fehler in Java. Ich finde sie selten, nur meine zweite in meiner 10-jährigen Karriere. Dies ist meine Lösung, wie andere erwähnt haben. Ich habe Nether benutzt
System.gc()
. Aber hier ist es in meinem Fall absolut entscheidend. Seltsam? JA!quelle
new File(path)
), bin ich auf das gleiche Problem gestoßen und habe es hinzugefügt,System.gc()
bevordelete()
es funktioniert hat!System.gc
Trick jedes Mal funktioniert.System.gc(); result = file.delete(); if (!result){ Thread.sleep(100); System.gc(); result = file.delete(); }
Es war ziemlich seltsam, welcher Trick funktionierte. Die Sache ist, wenn ich zuvor den Inhalt der Datei gelesen habe, die ich verwendet habe
BufferedReader
. Nach dem Lesen schloss ich den Puffer.Inzwischen habe ich gewechselt und jetzt lese ich den Inhalt mit
FileInputStream
. Auch nach dem Lesen schließe ich den Stream. Und jetzt funktioniert es.Das Problem ist, dass ich keine Erklärung dafür habe.
Ich weiß es nicht
BufferedReader
undFileOutputStream
inkompatibel.quelle
finalize()
, um die Reinigung zu gewährleisten? Oder vielleicht eingestelltto = null
? Siehe Erzwingen der Finalisierung und Speicherbereinigung .Ich habe diese einfache Sache ausprobiert und es scheint zu funktionieren.
Für mich geht das.
Wenn dies nicht funktioniert, versuchen Sie, Ihre Java-Anwendung unter sudo unter Linux und unter Windows als Administrator auszuführen. Nur um sicherzustellen, dass Java Rechte zum Ändern der Dateieigenschaften hat.
quelle
Bevor Sie versuchen , eine Datei zu löschen / umbenennen, müssen Sie sicherstellen , dass alle Leser oder Autoren (zB:
BufferedReader
/InputStreamReader
/BufferedWriter
) richtig geschlossen.Wenn Sie versuchen, Ihre Daten aus / in eine Datei zu lesen / schreiben, wird die Datei vom Prozess gehalten und erst freigegeben, wenn die Programmausführung abgeschlossen ist. Wenn Sie die Lösch- / Umbenennungsvorgänge ausführen möchten, bevor das Programm endet, müssen Sie die
close()
mit denjava.io.*
Klassen gelieferte Methode verwenden.quelle
Wie Jon Skeet kommentierte, sollten Sie Ihre Datei im Block finally ... schließen, um sicherzustellen, dass sie immer geschlossen ist. Und anstatt die Ausnahmen mit e.printStackTrace zu verschlucken, fangen Sie die Ausnahme einfach nicht ab und fügen Sie sie der Methodensignatur hinzu. Wenn Sie aus irgendeinem Grund nicht können, tun Sie zumindest Folgendes:
Nun Frage Nr. 2:
Was ist, wenn Sie dies tun:
Könnten Sie die Datei löschen?
Außerdem werden Dateien gelöscht, wenn sie geschlossen werden. Ich verwende IOUtils.closeQuietly (...), daher verwende ich die Flush-Methode, um sicherzustellen, dass der Inhalt der Datei vorhanden ist, bevor ich versuche, sie zu schließen (IOUtils.closeQuietly löst keine Ausnahmen aus). Etwas wie das:
Ich weiß also, dass der Inhalt der Datei dort ist. Da es mir normalerweise wichtig ist, dass der Inhalt der Datei geschrieben wird und nicht, ob die Datei geschlossen werden kann oder nicht, spielt es keine Rolle, ob die Datei geschlossen wurde oder nicht. In Ihrem Fall würde ich empfehlen, die Datei selbst zu schließen und Ausnahmen entsprechend zu behandeln.
quelle
Es gibt keinen Grund, warum Sie diese Datei nicht löschen können sollten. Ich würde schauen, wer diese Datei im Griff hat. Unter Unix / Linux können Sie mit dem Dienstprogramm lsof überprüfen, welcher Prozess die Datei sperrt. In Windows können Sie den Prozess-Explorer verwenden.
für lsof ist es so einfach wie zu sagen:
Für den Prozess-Explorer können Sie das Suchmenü verwenden und den Dateinamen eingeben, um das Handle anzuzeigen, das Sie auf den Prozess verweist, der die Datei sperrt.
Hier ist ein Code, der genau das tut, was Sie meiner Meinung nach tun müssen:
Es funktioniert gut unter OS X. Ich habe es nicht unter Windows getestet, aber ich vermute, dass es auch unter Windows funktionieren sollte. Ich gebe auch zu, dass bei der Verarbeitung von Windows-Wrt-Dateien ein unerwartetes Verhalten auftritt.
quelle
Wenn Sie in Eclipse IDE arbeiten, kann dies bedeuten, dass Sie die Datei beim vorherigen Start der Anwendung nicht geschlossen haben. Wenn ich beim Versuch, eine Datei zu löschen, dieselbe Fehlermeldung hatte, war dies der Grund. Es scheint, dass Eclipse IDE nach Beendigung einer Anwendung nicht alle Dateien schließt.
quelle
Hoffentlich hilft das. Ich stieß auf ein ähnliches Problem, bei dem ich meine Datei nicht löschen konnte, nachdem mein Java-Code eine Kopie des Inhalts in den anderen Ordner erstellt hatte. Nach ausgiebigem googeln habe ich explizit jede einzelne Dateioperationsvariable deklariert und die close () -Methode jedes Dateioperationsobjekts aufgerufen und auf NULL gesetzt. Dann gibt es eine Funktion namens System.gc (), die die Datei-E / A-Zuordnung aufräumt (ich bin nicht sicher, ich sage nur, was auf den Websites angegeben ist).
Hier ist mein Beispielcode:
quelle
Die Antwort ist, wenn Sie die Datei laden, müssen Sie die "Schließen" -Methode anwenden, in jeder Codezeile, die für mich funktioniert
quelle
Es gab einmal ein Problem in Ruby, bei dem Dateien in Windows ein "fsync" benötigten, um die Datei nach dem Schreiben und Schließen tatsächlich umdrehen und erneut lesen zu können. Vielleicht ist dies eine ähnliche Manifestation (und wenn ja, denke ich wirklich, ein Windows-Fehler).
quelle
Keine der hier aufgeführten Lösungen hat in meiner Situation funktioniert. Meine Lösung bestand darin, eine while-Schleife zu verwenden, um die Datei mit einer (konfigurierbaren) 5-Sekunden-Sicherheitsgrenze zu löschen.
Die Verwendung der obigen Schleife funktionierte ohne manuelles Sammeln von Müll oder Setzen des Streams auf Null usw.
quelle
Das Problem könnte sein, dass die Datei immer noch von einem Programm als geöffnet und gesperrt angesehen wird. oder vielleicht ist es eine Komponente aus Ihrem Programm, in der es geöffnet wurde, also müssen Sie sicherstellen, dass Sie die
dispose()
Methode verwenden, um dieses Problem zu lösen. dhJFrame frame; .... frame.dispose();
quelle
Sie müssen alle Streams schließen oder den Try-with-Resource-Block verwenden
quelle
Wenn file.delete () false sendet, wird Ihr Bufferedreader-Handle in den meisten Fällen nicht geschlossen. Einfach in der Nähe und es scheint für mich normal zu funktionieren.
quelle
Ich hatte das gleiche Problem unter Windows. Ich habe die Datei in Scala Zeile für Zeile mit gelesen
Jetzt lese ich es als Ganzes mit
Dadurch wird die Datei nach dem Lesen und jetzt ordnungsgemäß geschlossen
funktioniert.
quelle
Starten Sie Ihre IDE neu und führen Sie Ihren Code erneut aus. Dies ist nur eine Trickarbeit für mich nach einem einstündigen Kampf.
Hier ist mein Code:
Ausgabe:
Löschen
quelle
Ein weiterer Eckfall, in dem dies passieren könnte: Wenn Sie eine JAR-Datei über eine
URL
und später lesen / schreiben, versuchen Sie, dieselbe Datei innerhalb derselben JVM-Sitzung zu löschen.Grund dafür ist, dass die interne JAR-Dateiverarbeitungslogik von Java dazu neigt,
JarFile
Einträge zwischenzuspeichern:Und jede
JarFile
(vielmehr die zugrunde liegendeZipFile
Struktur) würde vom Zeitpunkt der Erstellung bis zumclose()
Aufruf ein Handle für die Datei enthalten :Zu diesem NetBeans-Problem gibt es eine gute Erklärung .
Anscheinend gibt es zwei Möglichkeiten, dies zu "beheben":
Sie können das Zwischenspeichern von JAR-Dateien deaktivieren - für die aktuelle
URLConnection
oder für alle zukünftigenURLConnection
s (global) in der aktuellen JVM-Sitzung:[HACK WARNING!] Sie können das manuell
JarFile
aus dem Cache löschen, wenn Sie damit fertig sind. Der Cache-Managersun.net.www.protocol.jar.JarFileFactory
ist paketprivat, aber etwas Reflexionszauber kann die Arbeit für Sie erledigen:Bitte beachten Sie: All dies basiert auf Java 8 codebase (
1.8.0_144
); Sie funktionieren möglicherweise nicht mit anderen / späteren Versionen.quelle