2010-02-07 10 views
7

Sto usando glib nella mia applicazione, e vedo che ci sono wrapper di convenienza in glib per C remove, unlink e rmdir. Ma questi funzionano solo su un singolo file o directory alla volta.Come camminare una directory in C

Per quanto posso vedere, né lo standard C né glib includono alcun tipo di funzionalità di lettura directory ricorsiva. Né vedo alcun modo specifico per eliminare un intero albero di directory in una volta, come con rm -rf.

per quello che sto facendo questo io non sono preoccupato per eventuali complicazioni come i permessi, i link simbolici di nuovo l'albero (ricorsione infinita), o qualsiasi cosa che possa escludere una molto ingenuo implementazione ... quindi non sono avverso a scrivere la mia propria funzione per questo.

Tuttavia, sono curioso di sapere se questa funzionalità è già disponibile da qualche parte nelle librerie standard gtk o glib (o in qualche altra libreria C facilmente riusabile) e non mi sono mai imbattuta in essa. Googling su questo argomento genera molti falsi lead.

Altrimenti il ​​mio piano è quello di utilizzare questo tipo di 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); 

Ovviamente vorrei costruire in qualche gestione degli errori e simili per interrompere il processo non appena viene rilevato un errore fatale.

+1

tecnicamente solo 'remove()' è nello standard C, gli altri 2 sono POSIX :) –

+0

Buono a sapersi, grazie. – mlibby

+1

Oltre alle risposte esistenti, tieni presente che non è sufficiente * percorrere una directory * in Mordor, sia in C che in qualsiasi altra lingua. –

risposta

4

È possibile utilizzare GFileEnumerator se si desidera farlo con glib.

+1

mi ricorda 'os.walk()' –

+0

Un GFileEnumerator è ricorsivo? Ho letto la documentazione ma non ne parla. Certo, posso provarlo e scoprire ... – mlibby

+2

No, non lo è. Ci sono pochi tutorial disponibili ma dovresti dare un'occhiata a http://gezeiten.org/post/2009/04/Writing-Your-Own-GIO-Jobs, che mostra l'elenco dei file ricorsivo (cerca "g_file_deep_count"). – AndiDog

2

Le librerie C standard hanno lo scopo di fornire funzionalità primitive. Quello di cui stai parlando è il comportamento composito. Puoi facilmente implementarlo utilizzando le funzioni di basso livello presenti nella tua API preferita: take a look at this tutorial.

7

Hai guardato <dirent.h>? AFAIK appartiene alla specifica POSIX, che dovrebbe far parte della libreria standard della maggior parte, se non di tutti i compilatori C. Vedi per es. this <dirent.h> reference (Single UNIX specification Version 2 by the Open Group).

P.S., prima che qualcuno commenta questo: No, questo non offre l'attraversamento di directory ricorsivo. Ma poi penso che questo sia meglio implementato dallo sviluppatore; i requisiti possono differire parecchio, quindi la funzione trasversale trasversale a misura unica dovrebbe essere molto potente. (Ad es .: i link simbolici sono seguiti? Se la profondità di ricorsione è limitata? Ecc.)

+0

Su Windows è opendir/closedir e simili. Oppure FindFirstFile TrovaNextFile. –

5

Diverse piattaforme includono ftw e nftw: "(nuovo) file tree walk". Il controllo della pagina man su un imac mostra che questi sono legacy, e i nuovi utenti dovrebbero preferire i fts. La portabilità può essere un problema con una di queste scelte.

-1

Nota che i "wrapper convenienza" si parla per remove(), scollegare() e rmdir(), supponendo che si intende quelli dichiarati nel <glib/gstdio.h>, non sono realmente "wrapper convenienza". Qual è la comodità nel prefisso di funzioni totalmente standard con un "g_"? (E si noti che lo dico anche se li ho introdotti in primo luogo.)

L'unico motivo per cui questi wrapper esistono è per problemi di nome file su Windows, dove questi wrapper consistono in realtà di codice reale; prendono gli argomenti del nome file in Unicode, codificati in UTF-8. Le corrispondenti funzioni di libreria Microsoft C "aperte" assumono nomi di file nella codepage di sistema.

Se non si sta specificamente scrivendo il codice destinato a essere portabile su Windows, non vi è alcun motivo per utilizzare i wrapper g_remove() ecc.

+2

La convenienza è che le versioni g_ gestiscono i casi di cui si discute. Dal momento che sto usando glib e gtk per molte altre cose, ha senso essere coerenti e usare le funzioni g_. In caso contrario, è sicuro che il mio codice non sarà portatile. Non intendevo implicare che le versioni g_ non facessero altro che chiamare la libreria standard. – mlibby

Problemi correlati