Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

360
Visualizações
Java | Intentar eliminar archivos en una máquina con Windows da como resultado "archivos fantasma"

Estoy tratando de eliminar algunos archivos en una máquina con Windows usando el método FileUtils.deleteDirectory de apache commons-io (la versión de la biblioteca commons es 2.4). Dicho método finalmente llama al método FileUtils "forceDelete" que llama a "file.delete()" en la línea 2273 aquí:

 2268 public static void forceDelete(File file) throws IOException { 2269 if (file.isDirectory()) { 2270 deleteDirectory(file); 2271 } else { 2272 boolean filePresent = file.exists(); 2273 if (!file.delete()) { 2274 if (!filePresent){ 2275 throw new FileNotFoundException("File does not exist: " + file); 2276 } 2277 String message = 2278 "Unable to delete file: " + file; 2279 throw new IOException(message); 2280 } 2281 } 2282 }

Ahora, file.delete, llama a FileSystem.delete(this) para el archivo en cuestión y esta es la parte en la que no estoy exactamente seguro de lo que sucede. Se supone que FileSystem.delete devuelve verdadero si el archivo se elimina y falso si hubo algún tipo de problema y el archivo no se eliminó. Al intentar eliminar el archivo, el método devuelve "verdadero", pero el archivo permanece en el directorio y, debido a que el directorio no se vacía correctamente, no se puede eliminar más tarde en el método FileUtils.deleteDirectory, lo que genera una excepción.

El archivo se puede eliminar manualmente, desde el explorador de archivos de Windows en cualquier momento hasta que se llame al método fileSystem.delete(this). Una vez que se llama a ese método, el explorador de archivos no puede eliminar el archivo y desaparece cuando se cierra la aplicación .

La razón por la que mencioné Windows varias veces es porque este problema no ocurre en máquinas Linux.

Lo que finalmente me lleva a mi pregunta: "¿Alguien sabe cuál podría ser la causa de este problema o al menos me da una idea de cómo obtener algunas respuestas?"

Este es mi primer post así que lo siento si hice algo mal, gracias de antemano.

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

java.io.File es una clase muy antigua. Fue parte del primer lanzamiento de Java en la década de 1990. El diseño orientado a objetos no se entendía tan bien en ese entonces, y la clase File tiene una serie de fallas, tanto en el diseño de la API como en la implementación.

Su reemplazo moderno es el paquete java.nio.file , en particular la clase Path para representar nombres de archivos y la clase Files (observe la 's') para realizar operaciones con archivos.

La misma funcionalidad, usando java.nio.file, podría verse así:

 public static void forceDelete(File file) throws IOException { Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { Files.delete(file); return super.visitFile(file, attrs); } @Override public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException { Files.delete(dir); return super.postVisitDirectory(dir, e); } }); }

El antiguo File.delete() no lanza una excepción; simplemente devuelve un booleano, y no tiene forma de saber por qué falló la operación. El paquete java.nio.file soluciona esto; obtendrá una excepción informativa si una operación falla. Por lo tanto, es posible que la implementación anterior no solucione el problema, pero al menos tendrá una buena idea de lo que sucedió.

over 4 years ago · Santiago Trujillo Relatório

0

El comportamiento es por diseño del subsistema NTFS del sistema operativo Windows: puede eliminar un archivo con éxito, pero permanece visible dentro del directorio contenedor siempre que algún (otro) proceso abra el archivo. Eso significa: solo cuando se cierre el último identificador del archivo, el archivo desaparecerá del sistema de archivos.

El nuevo libro Windows Internals, Part 2, 7th Edition cubre este tema en "Capítulo 11 --> El sistema de archivos NT --> Semántica de eliminación estilo POSIX" en las páginas 641, 642 en detalle.

Supongo que su aplicación Java ha abierto el archivo para lectura o escritura sin cerrarlo correctamente antes de llamar con éxito a File.delete() . O podría ser el objeto de la clase Java File en sí mismo, que mantiene un identificador abierto; no soy un experto en Java. En cualquier caso, el archivo permanecerá hasta que su JVM finalice o el objeto Archivo se recolecte como basura.

Pruébelo con Windows 10, actualización de mayo de 2019 (19H1) o posterior: Microsoft cambió la semántica predeterminada de la API DeleteFile() al estilo POSIX y su problema debería resolverse con eso;)

O use Files.delete(file) como señaló VGR en su respuesta anterior.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda