Me gustaría comprobar si el directorio está vacío en Java. Pero existe la posibilidad de que haya muchos archivos en ese directorio, así que me gustaría hacerlo sin consultar su lista de archivos, si es posible.Cómo comprobar si un directorio está vacío en Java
Respuesta
Con JDK7 puede usar Files.newDirectoryStream para abrir el directorio y luego usar el método hasNext() del iterador para probar que hay algún archivo para iterar (no olvide cerrar la secuencia). Esto debería funcionar mejor para directorios enormes o donde el directorio está en un sistema de archivos remoto en comparación con los métodos de la lista java.io.File.
Ejemplo:
private static boolean isDirEmpty(final Path directory) throws IOException {
try(DirectoryStream<Path> dirStream = Files.newDirectoryStream(directory)) {
return !dirStream.iterator().hasNext();
}
}
¿Cómo funcionaría si uno quisiera iterar sobre dirStream después del control? Intenté: for (Path artefact: dirStream) { Pero obtuve un Iterator ya obtenido - Excepción – garyee
Esto es una solución sucia, pero puede intentar eliminarlo (con el método delete
), y si la operación de eliminación falla, entonces el directorio no está vacío, si tiene éxito, entonces está vacío (pero tiene para volver a crearlo, y eso no es limpio). Continuaré buscando una mejor solución.
EDITAR: he encontrado walkFileTree de la clase java.nio.file.Files: http://download.java.net/jdk7/docs/api/java/nio/file/Files.html#walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor) problema es que se trata de Java 7 solamente.
He buscado S.O. para otras preguntas relacionadas con este mismo problema (enumerar archivos en un directorio sin usar la lista() que asigna memoria para una gran matriz) y la respuesta es bastante "no se puede, a menos que use JNI", que es a la vez plataforma dependiente y fea.
Si puede vivir con el código dependiente de la plataforma, puede intentar usar el código nativo actual cargando una biblioteca del sistema y usando sus API.
En Windows, por ejemplo, que tienen un Win32 API llamado FindFirstFile()
con el nombre del directorio ( sin una barra diagonal inversa). Si devuelve algo que no sea .
y ..
, sabrá que el directorio no está vacío. No mostrará todos los archivos, por lo que es mucho más rápido que file.list()
.
El equivalente en Unix es opendir
. Para sus propósitos, la lógica sería la misma.
Por supuesto, llamar a métodos nativos tiene un precio en la usabilidad y la carga inicial de la biblioteca que debería ser negada para cuando se ahorre en las consultas de FS.
Teniendo en cuenta que no hay absolutamente nada que impida a las personas crear archivos que no contengan un "." y nada que impida que las personas creen directorios que contengan un "." - Esa solución no servirá de nada. Y aunque estoy seguro de que hay una manera más o menos eficiente de hacer esto con una API nativa, la sobrecarga de llamarlo, probablemente será peor. Dependiendo de la implementación de FS, es concebible que el sistema operativo tenga que enumerar todos los archivos para comenzar de todos modos (¿no tiene idea de cómo se implementa NTFS?) – Voo
@Voo: el uso correcto es ignorar el '.' y' ..' entradas. Si un sistema de archivos no le permite obtener la primera entrada de directorio sin enumerar todos los archivos, no habría una forma rápida de verificar si está vacío, pero dudo que tal sistema de archivos exista alguna vez. – Gabe
@Gabe Sí, no tengo idea de cómo se implementa NTFS en detalle. Su solución editada debería ser exactamente lo que quiere el OP, aparte del hecho de que es nativo, y supongo que el directorio debe ser bastante grande para compensar el costo de la llamada nativa (pero ya lo mencionó y la pregunta es sobre grandes directorios de todos modos, así que está bien también). Aunque deberías haber creado una nueva publicación (la editada no tiene mucho en común con la original;)), me gustaría invitar a subir tu publicación (¿o recibes una parte del crédito debido a tu edición?) – Voo
Teniendo en cuenta desde java.io.File
source code, list()
método hace:
public java.lang.String[] list() {
...
byte[][] implList = listImpl(bs);
if (implList == null) {
// empty list
return new String[0];
}
...
}
private synchronized static native byte[][] listImpl(byte[] path);
Se invoca a un método nativo que pasa una matriz de bytes para obtener los archivos de la misma. Si un método devuelve null
, significa que el directorio está vacío.
Lo que significa, que no tienen ni siquiera un método nativo, para comprobar el vacío directorio sin el listado de archivos, por lo que no hay manera de que tendrían una implementación en Java para comprobar si el directorio está vacío.
Resultado: comprobar si el directorio está vacío sin listar archivos aún no está implementado en java.
Path checkIfEmpty=Paths.get("Pathtofile");
DirectoryStream<Path> ds = Files.newDirectoryStream(checkIfEmpty);
Iterator files = ds.iterator();
if(!files.hasNext())
Files.deleteIfExists(Paths.get(checkIfEmpty.toString()));
Solo tenga cuidado de cerrar DirectoryStream cuando termine (o use try-with-resources) de lo contrario terminará con una pérdida de controlador de archivos . – user194715
File parentDir = file.getParentFile();
if(parentDir.isDirectory() && parentDir.list().length == 0) {
LOGGER.info("Directory is empty");
} else {
LOGGER.info("Directory is not empty");
}
if(!Files.list(Paths.get(directory)).findAny().isPresent()){
Files.delete(Paths.get(directory));
}
Como files.list devolver una secuencia perezosamente poblada que va a resolver su problema de tiempo de ejecución relacionados.
También tuve esta confusión durante un tiempo largo sobre cómo comprobar si el Directorio estaba vacía o no Pero la respuesta es bastante simple uso
class isFileEmpty{
public static void main(String args[]){
File d = new File(//Path of the Directory you want to check or open);
String path = d.getAbsolutePath().toString();
File dir = new File(path);
File[] files = dir.listFiles();
if(!dir.exists()){
System.out.Println("Directory is Empty");
}
else{
for(int i =0;i<files.length;i++){
System.out.Println(files[i])
}
}
}
}
- 1. Comprobar si el directorio está vacío en Ruby
- 2. ¿Cómo comprobar si el objeto JSON está vacío en Java?
- 3. ¿Cómo comprobar si UITextFields está vacío?
- 4. ¿Cómo comprobar si $ _GET está vacío?
- 5. ¿Cómo comprobar si un archivo está vacío en Bash?
- 6. ¿Cómo comprobar si un valor está vacío en Lua?
- 7. C# comprobar si un directorio está oculto?
- 8. C# DataGridView Comprobar si está vacío
- 9. Compruebe si un directorio está vacío usando C en Linux
- 10. Cómo comprobar si hay un vacío Gridview
- 11. ¿Cómo comprobar si el objeto JSON está vacío en PHP?
- 12. La mejor manera de comprobar si un directorio está vacío con php
- 13. cómo comprobar si el campo de archivo está vacío?
- 14. ¿Cómo comprobar si HTML sessionStorage no está vacío?
- 15. Navaja MVC3: cómo comprobar si el modelo está vacío
- 16. ¿Cómo verifico si un repositorio está vacío?
- 17. Comprobar si el buzón está vacío en erlang
- 18. Cómo comprobar si mysql devuelve nulo/vacío
- 19. Cómo comprobar que ImageField está vacío
- 20. ¿Cómo verificar si jQuery datepicker está vacío?
- 21. ¿Cómo probar si un DataSet está vacío?
- 22. Cómo verificar si dynamic está vacío.
- 23. Comprobación de si un vector está vacío
- 24. objetivo comprobar si el campo de texto está vacío
- 25. AS3: compruebe si un diccionario está vacío
- 26. Cómo comprobar si un archivo no está vacío en el lote
- 27. ¿Cómo comprobar si un Textarea está vacío en JavaScript o Jquery?
- 28. compruebe si NSNumber está vacío
- 29. ¿Cómo comprobar si un hilo está durmiendo?
- 30. Cómo comprobar si el compilador JIT está desactivado en Java
lista() puede ser muy lento en muchos archivos. –
¿Cuántos archivos puede haber allí? ¿Realmente has encontrado problemas de rendimiento? – RonK
Al escanear directorios vacíos, encontré que .list() ocupaba más del 50% del tiempo de ejecución. Por lo tanto, encontrar una alternativa podría acelerar significativamente las cosas si realmente no necesita la lista de archivos. – cottonBallPaws