Как обойти каталог в C

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

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

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

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

Иначе мой план состоит в том, чтобы использовать этот тип алгоритма:

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

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

7
задан mlibby 7 February 2010 в 17:18
поделиться

5 ответов

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

5
ответ дан 6 December 2019 в 10:50
поделиться

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

5
ответ дан 6 December 2019 в 10:50
поделиться

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

2
ответ дан 6 December 2019 в 10:50
поделиться

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

-121--3842587-

В общем, это потому, что

  1. игры оптимальны в отношении того, что им нужно, и
  2. Они используют особые преимущества вашего оборудования.

Например, одна легкая оптимизация, которую вы можете сделать, включает в себя не попытки нарисовать вещи, которые невозможно увидеть. Рассмотрим сложную сцену, подобную городскому пейзажу от Grand Theft Auto IV . Визуализатор на самом деле не визуализирует все здания и сооружения. Вместо этого визуализируется только то, что может видеть камера. Если бы вы могли лететь на задние части тех же самых зданий, обращенные к оригинальной камере, вы бы увидели полузакрытую конструкцию оболочки. Каждая точка, которую камера не может увидеть, не визуализируется, так как вы ее не видите, нет необходимости пытаться показать ее вам.

Кроме того, оптимизированные инструкции и специальные методы существуют, когда вы разрабатываете на основе определенного набора аппаратных средств, чтобы обеспечить еще более высокую скорость.

Другой частью вашего вопроса является то, почему демонстрация использует столько ЦП:

... В то время как DX-демонстрация вращающегося Teapot @ 60fps использует колоссальный 30%?

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

Это имитирует функцию полностью полнофункционального аппаратного устройства, которое вряд ли существует, чтобы показать все функции API. Но поскольку оборудование на самом деле не существует, оно работает на вашем процессоре. Это гораздо неэффективнее, чем делегировать графическую карту - отсюда и высокая загрузка ЦП.

-121--622587-

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

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

7
ответ дан 6 December 2019 в 10:50
поделиться

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

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

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

-1
ответ дан 6 December 2019 в 10:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: