Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск директорий. 
:(
    Опции темы
SeregaLBN
Дата 28.2.2006, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 178
Регистрация: 3.10.2003
Где: Киев

Репутация: нет
Всего: нет



Собственно ф-ция написана (приведена ниже) - это обёртка над FindFirstFile, FindNextFile и FindClose.
Но в коде приходится делать проверку - не является ли указаное имя файлом...
Т.е., получается, для того чтобы перечислить все директории нужно перечислить и все файлы заодно.
А это меня не устраивает по скорости работы...

Как можно перечислять сразу только папки?


Я пытался использовать FindFirstFileEx, например, при таком вызове:
Код

   WIN32_FIND_DATA findFileData;
   HANDLE hFindFile = ::FindFirstFileEx(_T("C:\\"), FindExInfoStandard, &findFileData, FindExSearchLimitToDirectories, NULL, 0);

В результате hFindFile == INVALID_HANDLE_VALUE, а GetLastError() == ERROR_FILE_NOT_FOUND

А если делаю так:
Код

   WIN32_FIND_DATA findFileData;
   HANDLE hFindFile = ::FindFirstFileEx(_T("C:\\*"), FindExInfoStandard, &findFileData, FindExSearchLimitToDirectories, NULL, 0);

В результате hFindFile валидный, но всё равно приходится делать проверку:
Код

         if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {...}

т.к. приходят ещё и файлы.
Поэтому я для себя различий с FindFirstFile невижу...

Собственно, ф-ция поиска:
Код

typedef BOOL (CALLBACK* DIRENUMPROC )(IN LPCTSTR szDirName, IN LPCTSTR szSubDirName, IN LPVOID lpParam); // if return FALSE -> stop enumerators

BOOL EnumSubDir(IN LPCTSTR szDirName, IN DIRENUMPROC lpEnumFunc, IN LPVOID lpParam) {
   if (!szDirName || !szDirName[0] || !lpEnumFunc) {
      ::SetLastError(ERROR_INVALID_PARAMETER);
      return FALSE;
   }
   WIN32_FIND_DATA findFileData;
   HANDLE hFindFile = NULL;
   BOOL bRes = TRUE;
   DWORD dwErrCode = NO_ERROR;
   CString strDirName(szDirName);
   if (strDirName[strDirName.GetLength()-1] != _T('\\')) {
      strDirName += _T('\\');
   }
   do {
      if (hFindFile == NULL) {
         hFindFile = ::FindFirstFile(strDirName + _T('*'), &findFileData);
         bRes = (hFindFile != INVALID_HANDLE_VALUE);
      } else {
         bRes = ::FindNextFile(hFindFile, &findFileData);
      }
      if (!bRes) {
         DWORD dwErrCode = ::GetLastError();
         if (hFindFile == INVALID_HANDLE_VALUE) {
            if ((dwErrCode == ERROR_FILE_NOT_FOUND) ||
                (dwErrCode == ERROR_PATH_NOT_FOUND))
            {
               bRes = TRUE;
            }
         } else {
            if (dwErrCode == ERROR_NO_MORE_FILES) {
               bRes = TRUE;
            }
         }
         break;
      } else {
         if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            if (lstrcmp(findFileData.cFileName, _T(".")) &&
                lstrcmp(findFileData.cFileName, _T("..")))
            {
               bRes &= lpEnumFunc(szDirName, findFileData.cFileName, lpParam);
            }
            
         }
      }
   } while(bRes);
   if (hFindFile != INVALID_HANDLE_VALUE) {
      bRes = ::FindClose(hFindFile); hFindFile = NULL;
      if (!bRes) {
         dwErrCode = ::GetLastError();
         if (dwErrCode == ERROR_NO_MORE_FILES) {
            bRes = TRUE;
         }
      }
   }
   ::SetLastError(dwErrCode);
   return bRes;
}

PM MAIL   Вверх
Earnest
Дата 28.2.2006, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(MSDN)

FindExSearchLimitToDirectories
This is an advisory flag.
If the file system supports directory filtering, the function searches for a "file" that matches the specified file name and that is a directory.

If the file system does not support directory filtering, this flag is silently ignored.

The lpSearchFilter parameter of FindFirstFileEx must be NULL when this search operation is used.

If you want directory filtering, use this flag on all file systems, but be sure to examine the file attribute data stored into the *lpFindFileData parameter of FindFirstFileEx to determine whether the function has indeed returned a handle to a directory.

Особенно последние строки... smile



--------------------
...
PM   Вверх
SeregaLBN
Дата 28.2.2006, 17:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 178
Регистрация: 3.10.2003
Где: Киев

Репутация: нет
Всего: нет



Цитата(Earnest @ 28.2.2006, 17:09 Найти цитируемый пост)
Цитата(MSDN)
If you want directory filtering, use this flag on all file systems, but be sure to examine the file attribute data stored into the *lpFindFileData parameter of FindFirstFileEx to determine whether the function has indeed returned a handle to a directory.
Особенно последние строки... smile

Блин, читал и не увидел..
Жаль...

Но всё равно главный вопрос остался:
Цитата(SeregaLBN @ 28.2.2006, 16:52 Найти цитируемый пост)
Как можно перечислять сразу только папки?

Может есть альтернатива FindFirstFile, FindNextFile и FindClose?
PM MAIL   Вверх
Earnest
Дата 28.2.2006, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Честно говоря, не знаю, да и не вижу смысла: твой код ведь работает? А если хочешь его структурировать получше - ну напиши сам функции FindFirstDir, FindNextDir.


--------------------
...
PM   Вверх
adonin
Дата 1.3.2006, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 16.12.2005
Где: Новочеркасск Рост овская обл.

Репутация: 2
Всего: 5



Посмотрел File Functions в MSDN: ничего подходящего, кроме FindFirstFile, FindNextFile и FindClose не нашёл.
Поэтому ваш вариант - единственно правильный smile
--------------------
Тот, кто слизывает мед с крапивы, платит за него слишком дорого. (Томас ФУЛЛЕР)
PM MAIL   Вверх
Romikgy
Дата 1.3.2006, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



Цитата(SeregaLBN @ 28.2.2006, 16:20 Найти цитируемый пост)
Может есть альтернатива FindFirstFile, FindNextFile и FindClose?

Есть листбокс smile


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Fixin
Дата 2.3.2006, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ёжик
***


Профиль
Группа: Комодератор
Сообщений: 1357
Регистрация: 6.1.2004

Репутация: 8
Всего: 18



Цитата(Romikgy @ 1.3.2006, 13:50 Найти цитируемый пост)
Есть листбокс
Он ищет так же.

PM MAIL ICQ   Вверх
Romikgy
Дата 3.3.2006, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



Цитата(Fixin @ 2.3.2006, 18:44 Найти цитируемый пост)
Он ищет так же.

Может , зато пишется проще smile


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1663 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.