Estoy tratando de eliminar un archivo, después de escribir algo en él, con FileOutputStream
. Este es el código que utilizo para escribir:
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();
}
}
Como se ve, lavo y cierro el flujo, pero cuando trato de eliminar, file.delete()
devuelve falso.
He comprobado antes de la eliminación para ver si el archivo existe, y: file.exists()
, file.canRead()
, file.canWrite()
, file.canExecute()
todos vuelven realidad. Justo después de llamar a estos métodos, intento file.delete()
devolver falso.
¿Hay algo que haya hecho mal?
java
file
fileoutputstream
Jenny Smith
fuente
fuente
Respuestas:
Otro error en Java. Rara vez los encuentro, solo el segundo en mis 10 años de carrera. Esta es mi solución, como han mencionado otros. Yo no he usado
System.gc()
. Pero aquí, en mi caso, es absolutamente crucial. ¿Extraño? ¡SI!fuente
new File(path)
), encontré el mismo problema y agreguéSystem.gc()
antes dedelete()
que funcionara.System.gc
truco funciona siempre.System.gc(); result = file.delete(); if (!result){ Thread.sleep(100); System.gc(); result = file.delete(); }
Fue bastante extraño el truco que funcionó. La cosa es que cuando he leído previamente el contenido del archivo, usé
BufferedReader
. Después de leer, cerré el búfer.Mientras tanto cambié y ahora estoy leyendo el contenido usando
FileInputStream
. También después de terminar de leer cierro el arroyo. Y ahora está funcionando.El problema es que no tengo la explicación para esto.
No lo sé
BufferedReader
yFileOutputStream
ser incompatible.fuente
finalize()
para asegurar la limpieza? ¿O quizás listoto = null
? Consulte Forzar la finalización y la recolección de basura .Probé esta cosa simple y parece estar funcionando.
Esto funciona para mi.
Si esto no funciona, intente ejecutar su aplicación Java con sudo si está en Linux y como administrador cuando está en Windows. Solo para asegurarse de que Java tenga derechos para cambiar las propiedades del archivo.
fuente
Antes de intentar eliminar / cambiar el nombre de cualquier archivo, debe asegurarse de que todos los lectores o escritores (por ejemplo:
BufferedReader
/InputStreamReader
/BufferedWriter
) estén correctamente cerrados.Cuando intenta leer / escribir sus datos desde / hacia un archivo, el proceso lo retiene y no se libera hasta que se completa la ejecución del programa. Si desea realizar las operaciones de eliminación / cambio de nombre antes de que finalice el programa, debe utilizar el
close()
método que viene con lasjava.io.*
clases.fuente
Como comentó Jon Skeet, debe cerrar su archivo en el bloque finalmente {...}, para asegurarse de que siempre esté cerrado. Y, en lugar de tragar las excepciones con e.printStackTrace, simplemente no capte y agregue la excepción a la firma del método. Si no puede por alguna razón, al menos haga esto:
Ahora, pregunta número 2:
¿Qué pasa si haces esto?
¿Podrías borrar el archivo?
Además, los archivos se vacían cuando se cierran. Yo uso IOUtils.closeQuietly (...), así que uso el método flush para asegurarme de que el contenido del archivo esté ahí antes de intentar cerrarlo (IOUtils.closeQuietly no arroja excepciones). Algo como esto:
Entonces sé que el contenido del archivo está ahí. Como generalmente me importa que el contenido del archivo esté escrito y no si el archivo podría cerrarse o no, realmente no importa si el archivo se cerró o no. En su caso, como importa, le recomendaría cerrar el expediente usted mismo y tratar las excepciones de acuerdo.
fuente
No hay ninguna razón por la que no pueda eliminar este archivo. Miraría para ver quién tiene un control sobre este archivo. En unix / linux, puede usar la utilidad lsof para verificar qué proceso tiene un bloqueo en el archivo. En Windows, puede utilizar el explorador de procesos.
para lsof, es tan simple como decir:
para el explorador de procesos, puede usar el menú de búsqueda e ingresar el nombre del archivo para mostrarle el identificador que le indicará el proceso que bloquea el archivo.
aquí hay un código que hace lo que creo que debes hacer:
Funciona bien en OS X. No lo he probado en Windows, pero sospecho que también debería funcionar en Windows. También admitiré haber visto un comportamiento inesperado en el manejo de archivos wrt de Windows.
fuente
Si está trabajando en Eclipse IDE, eso podría significar que no ha cerrado el archivo en el lanzamiento anterior de la aplicación. Cuando tuve el mismo mensaje de error al intentar eliminar un archivo, esa fue la razón. Parece que Eclipse IDE no cierra todos los archivos después de la terminación de una aplicación.
fuente
Ojalá esto ayude. Me encontré con un problema similar en el que no pude eliminar mi archivo después de que mi código Java hiciera una copia del contenido en la otra carpeta. Después de una extensa búsqueda en Google, declaré explícitamente todas las variables relacionadas con la operación de archivo y llamé al método close () de cada objeto de operación de archivo, y los configuré en NULL. Luego, hay una función llamada System.gc (), que borrará el mapeo de E / S del archivo (no estoy seguro, solo digo lo que se da en los sitios web).
Aquí está mi código de ejemplo:
fuente
la respuesta es que cuando cargas el archivo, necesitas aplicar el método "cerrar", en cualquier línea de código, me funciona
fuente
Una vez hubo un problema en ruby donde los archivos en Windows necesitaban un "fsync" para poder volverse y volver a leer el archivo después de escribirlo y cerrarlo. Tal vez esta sea una manifestación similar (y si es así, creo que un error de Windows, en realidad).
fuente
Ninguna de las soluciones enumeradas aquí funcionó en mi situación. Mi solución fue usar un bucle while, intentando eliminar el archivo, con un límite de 5 segundos (configurable) por seguridad.
El uso del bucle anterior funcionó sin tener que hacer ninguna recolección manual de basura o configurar la transmisión en nulo, etc.
fuente
El problema podría ser que el archivo todavía se vea como abierto y bloqueado por un programa; o tal vez es un componente de su programa en el que se ha abierto, por lo que debe asegurarse de utilizar el
dispose()
método para resolver ese problema. es decirJFrame frame; .... frame.dispose();
fuente
Tienes que cerrar todas las transmisiones o usar el bloque try-with-resource
fuente
si file.delete () envía falso, en la mayoría de los casos, el identificador de Bufferedreader no se cerrará. Solo cerca y parece funcionar para mí normalmente.
fuente
Tuve el mismo problema en Windows. Solía leer el archivo en scala línea por línea con
Ahora lo leo completo con
que cierra el archivo correctamente después de leer y ahora
trabajos.
fuente
Reinicie su IDE y ejecute su código nuevamente, esto es solo un truco para mí después de una hora de lucha.
Aquí está mi código:
Salida:
Eliminar
fuente
Otro caso de esquina en el que esto podría suceder: si lee / escribe un archivo JAR a través de a
URL
y luego intenta eliminar el mismo archivo dentro de la misma sesión de JVM.La razón es que la lógica de manejo de archivos JAR interno de Java tiende a almacenar en caché las
JarFile
entradas:Y cada uno
JarFile
(más bien, laZipFile
estructura subyacente ) mantendría un identificador para el archivo, desde el momento de la construcción hasta queclose()
se invoca:Hay una buena explicación sobre este problema de NetBeans .
Aparentemente, hay dos formas de "arreglar" esto:
Puede deshabilitar el almacenamiento en caché de archivos JAR, para el actual
URLConnection
o para todos los correosURLConnection
electrónicos futuros (globalmente) en la sesión actual de JVM:[ADVERTENCIA DE HACK!] Puede purgar manualmente el
JarFile
de la caché cuando haya terminado con él. El administrador de cachésun.net.www.protocol.jar.JarFileFactory
es un paquete privado, pero algo de magia de reflexión puede hacer el trabajo por usted:Tenga en cuenta: Todo esto se basa en el código base de Java 8 (
1.8.0_144
); es posible que no funcionen con otras versiones o versiones posteriores.fuente