2011-06-17 113 views
13

¿Es esta la manera correcta de verificar si un directorio está vacío o no en C? ¿Hay una manera más eficiente de verificar si hay un directorio vacío, especialmente si tiene miles de archivos si no están vacíos?Compruebe si un directorio está vacío usando C en Linux

int isDirectoryEmpty(char *dirname) { 
    int n = 0; 
    struct dirent *d; 
    DIR *dir = opendir(dirname); 
    if (dir == NULL) //Not a directory or doesn't exist 
    return 1; 
    while ((d = readdir(dir)) != NULL) { 
    if(++n > 2) 
     break; 
    } 
    closedir(dir); 
    if (n <= 2) //Directory Empty 
    return 1; 
    else 
    return 0; 
} 

Si es un directorio vacío, readdir se detendrá después de las entradas '' y '..' y por lo tanto vacío si n<=2.

Si su vacío o no existe, debe devolver 1, el retorno demás 0

Actualización:

@c$ time ./isDirEmpty /fs/dir_with_1_file; time ./isDirEmpty /fs/dir_with_lots_of_files 
0 

real 0m0.007s 
user 0m0.000s 
sys 0m0.004s 

0 

real 0m0.016s 
user 0m0.000s 
sys 0m0.008s 

¿Por qué se necesita más tiempo para comprobar si hay un directorio con una gran cantidad de archivos en comparación a uno con solo un archivo?

Respuesta

8

¿Hay una manera más eficiente para comprobar para un directorio vacío, sobre todo si tiene 1000 de los archivos si no está vacío

La forma en que escribió su código no importa cuántos archivos que tiene (break si n> 2). Entonces su código usa un máximo de 5 llamadas. No creo que haya ninguna forma de (portátilmente) hacerlo más rápido.

+0

Lea mi edición, ¿por qué tarda más en ejecutarse el mismo código en un directorio con muchos archivos en comparación con uno con solo un archivo? – freethinker

+0

@freethinker No estoy seguro. Haz un "strace" y muéstranos eso. – cnicutar

+0

agregó las estrategias – freethinker

3
bool has_child(string path) 
{ 
    if(!boost::filesystem::is_directory(path)) 
     return false; 

    boost::filesystem::directory_iterator end_it; 
    boost::filesystem::directory_iterator it(path); 
    if(it == end_it) 
     return false; 
    else 
     return true; 
} 
+1

@freethinker está codificando en C. Los booleos no existen en C a menos que los defina con algo como: 'typedef enum {false, true} bool;'. – Larrimus

0

Tal vez este código podría ayudarle a:

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) { 
    char cmd[1024]; 
    char *folder = "/tmp"; 
    int status, exitcode; 

    if(argc == 2) 
      folder = argv[1]; 

    snprintf(cmd, 1024, "test $(ls -A \"%s\" 2>/dev/null | wc -l) -ne 0", folder); 
    printf("executing: %s\n", cmd); 

    status = system(cmd); 
    exitcode = WEXITSTATUS(status); 

    printf ("exit code: %d, exit status: %d\n", exitcode, status); 

    if (exitcode == 1) 
      printf("the folder is empty\n"); 
    else 
      printf("the folder is non empty\n"); 


    return 0; 
} 

puedo comprobar si la carpeta está vacía usando ls -a carpeta 2>/dev/null | wc -l, para contar los archivos en la carpeta, si devuelve cero, la carpeta está vacía, de lo contrario, la carpeta no estará vacía. La macro WEXITSTATUS, devuelve el código de salida del comando ejecutado.

Nota: si la carpeta no existe o no tiene los permisos correctos para acceder a ella, este programa debe imprimir "la carpeta está vacía".

Cuestiones relacionadas