2010-02-07 12 views
7

Używam glib w mojej aplikacji i widzę, że w glib znajdują się opakowania po stronie wygody dla C: remove, unlink i rmdir. Ale działają one tylko na pojedynczym pliku lub katalogu na raz.Jak przejść do katalogu w C

O ile widzę, ani standard C, ani glib nie zawierają żadnej funkcji rekursywnego chodzenia do katalogu. Nie widzę też żadnego konkretnego sposobu na usunięcie całego drzewa katalogów na raz, tak jak w przypadku rm -rf.

Za to, co robię, nie martwię się żadnymi komplikacjami, takimi jak uprawnienia, dowiązania symboliczne tworzą kopię zapasową drzewa (nieskończona rekursja) lub cokolwiek, co wyklucza bardzo naiwne wdrożenie ... więc nie jestem nie podoba mi się napisanie mojej własnej funkcji.

Jednak jestem ciekawy, czy ta funkcjonalność jest gdzieś w standardowych bibliotekach gtk lub glib (lub w jakiejś innej łatwo używanej bibliotece C), a ja po prostu nie natknąłem się na to. Googling w tym temacie generuje wiele fałszywych tropów.

przeciwnym razie mój plan jest do korzystania z tego rodzaju algorytmu:

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); 

Oczywiście chciałbym zbudować w pewnym obsługi błędów i tym podobne, aby przerwać proces tak szybko, jak to błąd krytyczny spotyka.

+1

technicznie tylko 'remove()' jest w standardzie C, pozostałe 2 to POSIX :) –

+0

Dobrze wiedzieć, dziękuję. – mlibby

+1

Oprócz istniejących odpowiedzi, należy pamiętać, że nie wystarczy po prostu * przejść do katalogu * w Mordorze, czy to w języku C, czy w jakimkolwiek innym języku. –

Odpowiedz

4

Możesz użyć GFileEnumerator, jeśli chcesz to zrobić za pomocą glib.

+1

przypomina mi 'os.walk()' –

+0

Czy rekursywny GFileEnumerator? Czytam dokumentację, ale o tym nie wspomina. Oczywiście, mogę spróbować i dowiedzieć się ... – mlibby

+2

Nie, nie jest. Dostępnych jest kilka samouczków, ale powinieneś rzucić okiem na http://gezeiten.org/post/2009/04/Writing-Your-Own-GIO-Jobs, który pokazuje listę rekursywnych plików (szukaj "g_file_deep_count"). – AndiDog

2

Standardowe biblioteki C mają zapewnić prymitywną funkcjonalność. To, o czym mówisz, to zachowanie złożone. Możesz go łatwo wdrożyć, korzystając z funkcji niskiego poziomu dostępnych w wybranym interfejsie API - take a look at this tutorial.

7

Czy spojrzałeś na <dirent.h>? AFAIK to należy do specyfikacji POSIX, która powinna być częścią standardowej biblioteki większości, jeśli nie wszystkich kompilatorów języka C. Zobacz np. this <dirent.h> reference (Single UNIX specification Version 2 by the Open Group).

P.S., zanim ktoś wypowie się na ten temat: Nie, to nie oferuje rekursywnego przeglądania katalogów. Ale myślę, że to najlepiej jest implementowane przez programistę; wymagania mogą się bardzo różnić, więc uniwersalna funkcja rekursywna musi być bardzo potężna. (Np .: Czy dowiązania symboliczne są kontynuowane? Czy głębokość rekurencji jest ograniczona?) Itp.)

+0

W Windowsie to opendir/closedir i tym podobne. Lub FindFirstFile FindNextFile. –

5

Kilka platform zawiera ftw i nftw: "(nowe) drzewo plików". Sprawdzanie strony man na imacu pokazuje, że są one starsze, a nowi użytkownicy powinni preferować fts. Przenoszenie może być problemem z którymkolwiek z tych wyborów.

-1

Zauważ, że "owijarki convenience" wspomina o remove(), odłączyć() oraz rmdir(), zakładając, że masz na myśli te deklarowane w <GLib/gstdio.h>, nie są naprawdę "owijarki convenience". Co to jest wygoda w przedrostowaniu całkowicie standardowych funkcji za pomocą "g_"? (Zwróćcie uwagę, że mówię to, nawet jeśli ja, który je przedstawiłem).

Jedyny powód istnienia tych wrapperów dotyczy problemów z nazwami plików w systemie Windows, gdzie te opakowania faktycznie składają się z prawdziwego kodu; pobierają argumenty nazwy pliku w Unicode, kodowane w UTF-8. Odpowiednie "nieopakowane" funkcje biblioteki Microsoft C pobierają nazwy plików na stronie kodowej systemu.

Jeśli nie piszesz specjalnie kodu, który ma być przenośny dla systemu Windows, nie ma powodu, aby używać programów do pakowania g_remove() itp.

+2

Wygoda jest taka, że ​​wersje g_ obsługują omawiane przypadki. Ponieważ używam glib i gtk dla wielu innych rzeczy, ma sens być spójny i używać funkcji g_. Nie czyniąc tego, upewniamy się, że mój kod nie będzie przenośny. Nie miałem zamiaru sugerować, że wersje g_ zrobiły tylko zwykłą bibliotekę. – mlibby

Powiązane problemy