#c #winapi
#c #winapi
Вопрос:
Я работаю в независимом от операционной системы файловом менеджере, и у меня возникла проблема с правильным определением, является ли файл каталогом или нет в Windows. dirent
Структура в Windows, похоже, не имеет DT_DIR
поля, поэтому я использую:
file_attributes=GetFileAttributes(ep->d_name);
if(file_attributes amp; FILE_ATTRIBUTE_DIRECTORY)files_list[i].is_dir=1;
else files_list[i].is_dir=0;
Однако это не всегда точно, поскольку некоторые файлы помечены как каталоги (например, pagefile.sys ). Кроме того, GetFileAttributes
это довольно медленно, если у вас много файлов.
У меня также есть функция:
int does_dir_exist(char *path)
{
DIR *dp_test;
dp_test = opendir(path);
if(dp_test)
{
return 1;
closedir(dp_test);
}
return 0;
}
Но это довольно медленно (не рекомендуется делать это для 10000 файлов).
Конечно, я могу объединить оба, что было бы довольно быстро, но есть ли лучший способ?
PS По какой-то причине не удается правильно отформатировать код для второй функции.
Комментарии:
1. Что заставляет вас говорить, что
GetFileAttributes
это медленно. Я далеко не уверен, что вы можете найти что-нибудь быстрее.2. Мне трудно поверить, что некоторые файлы (такие как pagefile.sys ) имеет
FILE_ATTRIBUTE_DIRECTORY
включенный флаг. Возможно, вGetFileAttributes
конечном итоге вы получите код ошибки -1, в котором установлены все биты3. Я прокомментировал это, и без него это намного быстрее. И в Linux это быстрее (поскольку мне не нужно этого делать). Если у вас в каталоге около 2 тысяч файлов, и вы не обращались
GetFileAttributes
к ним в последнее время, это может занять несколько секунд.4. Валдо, спасибо, это было так! Пожалуйста, укажите это в качестве ответа.
5. Да, это, конечно, правда, что a
nop
довольно быстро вычисляется, но это не значит, что все программы могут работать так же быстро, какnop
.
Ответ №1:
Просто используйте GetFileAttributes()
. opendir
и closedir
не собираются быстрее (вы его профилировали? Вы повторяли свои тесты, чтобы избежать эффектов кэша?).
Да, GetFileAttributes()
точно. Причина, по которой вы думаете, что он терпит неудачу, заключается в том, что когда вы пытаетесь получить атрибуты pagefile.sys
, он терпит неудачу и возвращается INVALID_FILE_ATTRIBUTES
, что и есть (DWORD)-1
. Когда вы проверяете это с FILE_ATTRIBUTE_DIRECTORY
помощью, он возвращает true , потому -1
что в нем установлен каждый бит.
На скольких файлах вы запускаете это? Какую бы функцию вы ни использовали, это будет операция, связанная с вводом-выводом, поскольку для определения атрибутов файла родительский каталог должен быть прочитан с диска (или из дискового кэша).
Комментарии:
1. Да, это было так, спасибо. Я не использую opendir / closedir для этой цели, это просто для определения где-то еще в коде, существует ли каталог или нет (и он мультиплатформенный). Метод, который я использую, — это opendir / readdir для чтения файлов, поскольку он имеет несколько шаблонов.
Ответ №2:
_wfinddata_t fd;
_wfindfirst
_wfindnext
_findclose
Если вы используете эти методы для определения элементов в папке, вы получаете результат GetFileAttributes бесплатно.
Комментарии:
1. Спасибо, но я хочу, чтобы большая часть моего кода была как можно более независимой от платформы. Но рассмотрю ваше предложение, если у меня будет немного свободного времени для изменения этого кода.