Jak skanować katalog dla folderów i plików w C? Musi być wieloplatformowy.Jak uzyskać listing katalogu w C?
Odpowiedz
opendir/readdir to POSIX. Jeśli POSIX nie wystarcza do przenoszenia, który chcesz osiągnąć, sprawdź Apache Portable Runtime
Poniższa wypisze nazwy plików w bieżącym katalogu:
#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>
int main (void)
{
DIR *dp;
struct dirent *ep;
dp = opendir ("./");
if (dp != NULL)
{
while (ep = readdir (dp))
puts (ep->d_name);
(void) closedir (dp);
}
else
perror ("Couldn't open the directory");
return 0;
}
(kredytową: http://www.gnu.org/software/libtool/manual/libc/Simple-Directory-Lister.html)
The Surowa odpowiedź brzmi "nie możesz", ponieważ sama koncepcja folderu nie jest prawdziwie wieloplatformowa.
Na platformach MS można używać _findfirst, _findnext i _indexclose dla poczucia "c", oraz FindFirstFile i FindNextFile dla podstawowych wywołań Win32.
Oto C-FAQ odpowiedź:
czy istnieje już alias dla ustawienia _findfirst, _findnext i _findclose? nie w windows.h prawda? – BuddyJoe
Nie ma standardowej C (lub C++) sposób wyliczyć pliki w katalogu.
W systemie Windows można użyć funkcji FindFirstFile/FindNextFile w celu wyliczenia wszystkich pozycji w katalogu. W systemie Linux/OSX użyj funkcji opendir/readdir/closedir.
Lista pozycji jest bardzo różna w zależności od rozważanego systemu operacyjnego/platformy. Wynika to z faktu, że różne systemy operacyjne wykorzystujące własne wewnętrzne wywołania systemowe do osiągnięcia tego celu.
Rozwiązaniem tego problemu byłoby wyszukanie biblioteki, która maskuje ten problem i jest przenośna. Niestety, nie ma rozwiązania, które działa bezbłędnie na wszystkich platformach.
W systemach zgodnych z POSIX można użyć biblioteki do uzyskania tego za pomocą kodu opublikowanego przez Clayton (który jest przywoływany pierwotnie z Zaawansowanego programowania w książce UNIX autorstwa W. Richarda Stevensa). to rozwiązanie będzie działać w systemach * NIX i będzie działało również w systemie Windows, jeśli masz zainstalowane Cygwin.
Alternatywnie można napisać kod w celu wykrycia podstawowego systemu operacyjnego, a następnie wywołać odpowiednią funkcję listy katalogów, która będzie posiadała "właściwy" sposób wyświetlania struktury katalogów w tym systemie operacyjnym.
GLib to biblioteka przenośności dla biblioteki C, która stanowi podstawę zestawu narzędzi graficznych GTK +. Może być używany jako samodzielna biblioteka.
Zawiera przenośne opakowania do zarządzania katalogami. Szczegółowe informacje można znaleźć w dokumentacji Glib File Utilities.
Osobiście nawet nie rozważałbym pisania dużych ilości kodu C bez czegoś takiego jak GLib za mną. Łatwość w przenoszeniu to jedno, ale fajnie jest zdobyć struktury danych, pomocników wątków, zdarzenia, mainloopy itp. Za darmo.
Jike, prawie zaczynam brzmieć jak facet od sprzedaży :) (nie martw się, glib jest open source (LGPL) i nie jestem związany z nim w żaden sposób)
+1; Odpowiednią funkcją jest 'g_dir_read_name()' – weiqure
najbardziej podobny metoda readdir
jest prawdopodobnie za pomocą mało znany _find
family of functions.
Utworzono otwarty nagłówek C (open source) (BSD), który zajmuje się tym problemem. Obecnie obsługuje POSIX i Windows. Proszę to sprawdzić:
https://github.com/cxong/tinydir
tinydir_dir dir;
tinydir_open(&dir, "/path/to/dir");
while (dir.has_next)
{
tinydir_file file;
tinydir_readfile(&dir, &file);
printf("%s", file.name);
if (file.is_dir)
{
printf("/");
}
printf("\n");
tinydir_next(&dir);
}
tinydir_close(&dir);
W jaki sposób pomaga to więcej niż oryginalne implementacje zależne od systemu? Czy jest tak, że potrzebujesz tylko jednej nazwanej biblioteki dla Windows i POSIX? – kevr
"zagłosuj" na tinydir.h, Dobra robota. –
można znaleźć przykładowy kod na wikibooks link
/**************************************************************
* A simpler and shorter implementation of ls(1)
* ls(1) is very similar to the DIR command on DOS and Windows.
**************************************************************/
#include <stdio.h>
#include <dirent.h>
int listdir(const char *path)
{
struct dirent *entry;
DIR *dp;
dp = opendir(path);
if (dp == NULL)
{
perror("opendir");
return -1;
}
while((entry = readdir(dp)))
puts(entry->d_name);
closedir(dp);
return 0;
}
int main(int argc, char **argv) {
int counter = 1;
if (argc == 1)
listdir(".");
while (++counter <= argc) {
printf("\nListing %s...\n", argv[counter-1]);
listdir(argv[counter-1]);
}
return 0;
}
To powinno działać w systemie Windows, jak również, co najmniej z MinGW. –
@Clayton ale uczono mnie, że nigdy nie używa puts(), ponieważ nie wie, ile znaków do wydrukowania? – YakRangi
Co z tego: 'error: unknown type name 'off64_t'' –