2010-02-07 14 views
7

Estoy usando glib en mi aplicación, y veo que hay envolturas de conveniencia en glib para C remove, unlink y rmdir. Pero estos solo funcionan en un solo archivo o directorio a la vez.Cómo caminar un directorio en C

Por lo que puedo ver, ni el estándar C ni el glib incluyen ningún tipo de funcionalidad de recorrido recíproco de directorio. Tampoco veo ninguna forma específica de eliminar un árbol de directorios completo a la vez, como con rm -rf.

Por lo que estoy haciendo esto no estoy preocupado por ninguna complicación como permisos, enlaces simbólicos de respaldo al árbol (recursión infinita), o cualquier cosa que descarte una implementación muy ingenua ... así que no estoy reacio a escribir mi propia función para ello.

Sin embargo, tengo curiosidad por saber si esta funcionalidad ya existe en alguna parte de las bibliotecas estándar gtk o glib (o en alguna otra biblioteca C fácilmente reutilizable) y no me he topado con ella. Buscar en Google este tema genera muchas pistas falsas.

De lo contrario mi plan es utilizar este tipo de algoritmo:

dir_walk(char* path, void* callback(char*) { 
    if(is_dir(path) && has_entries(path)) { 
    entries = get_entries(path); 
    for(entry in intries) { dir_walk(entry, callback); } 
    } 
    else { callback(path) } 
} 

dir_walk("/home/user/trash", remove); 

Obviamente construirían en alguna manejo de errores y similares para abortar el proceso tan pronto como se detecta un error fatal.

+1

técnicamente solo 'remove()' está en el estándar C, los otros 2 son POSIX :) –

+0

Es bueno saberlo, gracias. – mlibby

+1

Además de las respuestas existentes, tenga en cuenta que no se debe simplemente * llevar un directorio * a Mordor, ya sea en C o en cualquier otro idioma. –

Respuesta

4

Puede usar GFileEnumerator si desea hacerlo con glib.

+1

me recuerda 'os.walk()' –

+0

¿Es un GFileEnumerator recursivo? Leo la documentación pero no menciona esto. Por supuesto, puedo intentarlo y descubrir ... – mlibby

+2

No, no lo es. Hay pocos tutoriales disponibles, pero debe consultar http://gezeiten.org/post/2009/04/Writing-Your-Own-GIO-Jobs, que muestra una lista recursiva de archivos (busque "g_file_deep_count"). – AndiDog

2

Las bibliotecas estándar C están diseñadas para proporcionar funcionalidad primitiva. De lo que estás hablando es de comportamiento compuesto. Puede implementarlo fácilmente utilizando las características de bajo nivel presentes en su API de elección: take a look at this tutorial.

7

¿Has mirado <dirent.h>? AFAIK esto pertenece a la especificación POSIX, que debe ser parte de la biblioteca estándar de la mayoría, si no de todos los compiladores de C. Ver p. this <dirent.h> reference (Single UNIX specification Version 2 by the Open Group).

P.S., antes de que alguien comente sobre esto: No, esto no ofrece un recorrido de directorio recursivo. Pero luego creo que esto es mejor implementado por el desarrollador; los requisitos pueden diferir bastante, por lo que una función transversal recursiva de un tamaño adecuado tendría que ser muy poderosa. (Por ejemplo: ¿se siguen los enlaces simbólicos? ¿Se debe limitar la profundidad de recursión ?, etc.)

+0

En windows es opendir/closedir y similares. O FindFirstFile FindNextFile. –

5

Varias plataformas incluyen ftw y nftw: "(nuevo) árbol de archivos a pie". La comprobación de la página man en un imac muestra que estos son heredados, y los nuevos usuarios deberían preferir los fts. La portabilidad puede ser un problema con cualquiera de estas opciones.

-1

Tenga en cuenta que los "envoltorios de conveniencia" que mencionan a remove(), desvincular() y rmdir(), suponiendo que se refiere a los declarados en <simplista/gstdio.h>, no son realmente "envolturas de conveniencia". ¿Cuál es la conveniencia de anteponer funciones totalmente estándar con un "g_"? (Y tenga en cuenta que digo esto incluso si los introduje en primer lugar.)

La única razón por la que existen estos envoltorios es por problemas de nombres de archivos en Windows, donde estos envoltorios en realidad consisten en código real; toman argumentos de nombre de archivo en Unicode, codificados en UTF-8. Las correspondientes funciones de biblioteca de Microsoft C "sin envolver" toman los nombres de archivo en la página de códigos del sistema.

Si no está escribiendo específicamente código destinado a ser portátil para Windows, no hay ninguna razón para utilizar los contenedores g_remove() etc.

+2

La conveniencia es que las versiones g_ manejan los casos que discute. Como uso glib y gtk para muchas otras cosas, tiene sentido ser consistente y usar las funciones g_. No hacerlo así asegura que mi código no sea portátil. No quise dar a entender que las versiones g_ hicieran nada más que llamar a la biblioteca estándar. – mlibby

Cuestiones relacionadas