Как пройти каталог в C - PullRequest
       99

Как пройти каталог в C

7 голосов
/ 07 февраля 2010

Я использую glib в своем приложении и вижу, что в glib есть удобные обёртки для C remove, unlink и rmdir. Но они работают одновременно только с одним файлом или каталогом.

Насколько я вижу, ни стандарт C, ни glib не включают в себя никакой рекурсивной функциональности обхода каталога. Также я не вижу какого-либо конкретного способа удалить все дерево каталогов сразу, как с rm -rf.

За то, что я делаю, я не беспокоюсь о каких-либо сложностях, таких как разрешения, символические ссылки на дерево (бесконечная рекурсия) или что-либо, что исключает очень наивный реализация ... так что я не против написания своей собственной функции для него.

Однако мне любопытно, есть ли эта функциональность где-то в стандартных библиотеках gtk или glib (или в какой-либо другой легко повторно используемой библиотеке C), и я просто не наткнулся на это. Поиск в этой теме порождает множество ложных сведений.

В противном случае я планирую использовать этот тип алгоритма:

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

Очевидно, я бы встроил некоторую обработку ошибок и тому подобное, чтобы прервать процесс, как только возникнет фатальная ошибка.

Ответы [ 5 ]

7 голосов
/ 07 февраля 2010

Вы смотрели на <dirent.h>? AFAIK это относится к спецификации POSIX, которая должна быть частью стандартной библиотеки большинства, если не всех компиляторов Си. Смотрите, например это <dirent.h> ссылка ( Одиночная версия UNIX версии 2 от Open Group) .

P.S. , прежде чем кто-то прокомментирует это: Нет, это не дает рекурсивного обхода каталога. Но тогда я думаю, что это лучше всего реализовано разработчиком; требования могут сильно различаться, поэтому рекурсивная функция обхода для одного размера должна быть очень мощной. (Например: отслеживаются ли символические ссылки? Должна ли быть ограничена глубина рекурсии? И т. Д.)

5 голосов
/ 07 февраля 2010

Некоторые платформы включают в себя ftw и nftw: «(новый) обход дерева файлов». Проверка страницы справочника на imac показывает, что они являются устаревшими, и новые пользователи должны предпочесть fts. Переносимость может быть проблемой с любым из этих вариантов.

4 голосов
/ 07 февраля 2010

Вы можете использовать GFileEnumerator , если вы хотите сделать это с помощью glib.

2 голосов
/ 07 февраля 2010

Стандартные библиотеки C предназначены для обеспечения примитивной функциональности. То, о чем вы говорите, это сложное поведение. Вы можете легко реализовать его, используя низкоуровневые функции, имеющиеся в выбранном вами API - , посмотрите на это руководство .

0 голосов
/ 15 февраля 2010

Обратите внимание, что "вспомогательные упаковщики", которые вы упоминаете для remove (), unlink () и rmdir (), предполагая, что вы имеете в виду те, которые объявлены в , на самом деле не являются "вспомогательными упаковщиками". Каково удобство в добавлении префикса полностью стандартных функций к «g_»? (И обратите внимание, что я говорю это, даже если бы я представил их в первую очередь.)

Единственная причина, по которой существуют эти оболочки, связана с проблемами с именами файлов в Windows, где эти оболочки фактически состоят из реального кода; они принимают аргументы имени файла в Unicode, закодированные в UTF-8. Соответствующие «развернутые» функции библиотеки Microsoft C принимают имена файлов в системной кодовой странице.

Если вы специально не пишете код, предназначенный для переноса в Windows, нет никаких оснований использовать оболочки g_remove () и т. Д.

...