Показать полную графическую версию : WinApi||посчитать сколько файлов и папок на диске
Здравствуйте. Подскажите пожалуйста, почему у меня при подсчете кол-ва файлов и папок на диске это количество не соответствует действительности.
for( int i = 0; i < 26; i++ )
{//запускаем цикл с целью опросить все устройства
if(i==0)
{
hFirstFile = FindFirstFile(_T("a:\*.?*"), &wfd);
hFirstFile1 = FindFirstFile(_T("a:\*."), &wfd);
}
else
if(i==2)
{
hFirstFile = FindFirstFile(_T("C:\*.?*"), &wfd);
hFirstFile1 = FindFirstFile(_T("C:\*"), &wfd);
}
else
if(i==3)
{
hFirstFile = FindFirstFile(_T("d:\*.?*"), &wfd);
hFirstFile1 = FindFirstFile(_T("d:\*"), &wfd);
}
else
{
hFirstFile = FindFirstFile(_T("bb:\*.?*"), &wfd);
hFirstFile1 = FindFirstFile(_T("bb:\*."), &wfd);
}
if (hFirstFile != INVALID_HANDLE_VALUE)
{
do
{
nFilesCount =1+nFilesCount;
}
while (FindNextFile(hFirstFile, &wfd));
}
if (hFirstFile1 != INVALID_HANDLE_VALUE)
{
do
{
nFilesCount1 =1+nFilesCount1;
}
while (FindNextFile(hFirstFile1, &wfd));
}
nFilesCount=0;nFilesCount1=0;
}
Diseased Head
18-12-2006, 22:50
Погоди-ка, чёт не понял:
hFirstFile = FindFirstFile(_T("a:\*.?*"), &wfd); // Попытка создать указатель на файлы?
hFirstFile1 = FindFirstFile(_T("a:\*."), &wfd); // Попытка создать указатель на папки?
Так что-ли? А если файл без расшерения? Тогда он будет видится как папка. И почему ты тогда не поставил точки, в следующей части, своего, кода:
if(i==2)
{
hFirstFile = FindFirstFile(_T("C:\*.?*"), &wfd);
hFirstFile1 = FindFirstFile(_T("C:\*."), &wfd);
}
else
if(i==3)
{
hFirstFile = FindFirstFile(_T("d:\*.?*"), &wfd);
hFirstFile1 = FindFirstFile(_T("d:\*."), &wfd);
}
Я их поставил красным цветом. Или я чёт не допонял...
Vovchick1
18-12-2006, 23:06
bezumes
Сам не пробовал, но судя повсему FindFirstFile - найти первый файл, следовательно следующие файлы в каталоге находятся FindNextFile.
Насколько япомню "?" это 1 любой символ, и чем тогда "*.?*" отличается от "*.*"
Diseased Head
"*" это любая последовательность любых символов, а "*." это значет в конце должна стоять точка наример "ReadMe."
Diseased Head
19-12-2006, 00:30
Vovchick1и чем тогда "*.?*" отличается от "*.*"Да я в общем-то к этому и клонил...
"*" это любая последовательность любых символов, а "*." это значет в конце должна стоять точка наример "ReadMe."Мож так: "*" значит все файлы и папки (с расширением и без), а "*." папки без расширения и файлы без расширения. Точнее, в конце должна стоять только точка. А можно и так: "*." - "все символы до точки, включая саму точку".
aESThete
19-12-2006, 09:37
bezumes
Обратите внимание на неправильный инкремент (лишний "+"):
if (hFirstFile != INVALID_HANDLE_VALUE)
{
do
{
nFilesCount +=1+nFilesCount; // и вообще почему не поставить просто nFilesCount++
}
while (FindNextFile(hFirstFile, &wfd));
}
И по маскам: я так понял, что у вас hFirstFile для файлов, а hFirstFile1 для каталогов. Каталоги(папки) тоже могут иметь расширение, так и файлы могут быть без расширения.
Попробуйте сделать одну маску "*.*" и уже потом по атрибутам разделять каталоги и файлы.
Или задача другая: "подсчитать количество отдельно с расширением и без расширения"?
PS для красоты и уменьшения кода я бы посоветовал букву диска формировать.
PPS Только что обратил внимание: вам нужно подсчитать каталоги и папки только в корне диска?
и чем тогда "*.?*" отличается от "*.*"
как чем, в первом случае расширение 1 символ а во втором любое количество.
Так что-ли? А если файл без расширения? Тогда он будет видится как папка А нечего такие файлы на диске держать :)
И почему ты тогда не поставил точки, в следующей части, своего, кода
Там я задумывал что найдутся все папки ,неподумал о том что и папки с расширением могут быть, так что А нечего такие папки на диске держать :)
Сам не пробовал, но судя повсему FindFirstFile - найти первый файл, следовательно следующие файлы в каталоге находятся FindNextFile. Ну у меня же
if (hFirstFile != INVALID_HANDLE_VALUE)
{
do
{
//вот только у меня возникают сомнения в правильности выполнения этого цикла
nFilesCount =1+nFilesCount;
}
while (FindNextFile(hFirstFile, &wfd));
делать пока новые файлы/папки находит.
Или задача другая: "подсчитать количество отдельно с расширением и без расширения"? Не, нужно подсчитать количество файлов и папок каждом устройстве
PPS Только что обратил внимание: вам нужно подсчитать каталоги и папки только в корне диска?
Вообще-то нет, но я еще не придумал как искать еще и во вложеных папках.
aESThete
19-12-2006, 17:00
bezumes
К сожалению, под рукой C++ освежить в памяти синтаксис и функции нету, а не программировал на С я давно.
Попробую составить примерный алгоритм на "псевдо-C++" (дикой смеси си и васика).
функция ПосчитатьВсеДиски()
{
for( int i = 0; i < 26; i++ ) //запускаем цикл с целью опросить все устройства
{
Файлов = 0;
Папок = 0;
ПосчитатьКаталог(char("a"+i) + ":\", Файлов, Папок); // char("a"+i) для переносимости не совсем правильно, надо бы массив букв дисков
printf("На диске %c %d файлов, %d папок.", char("a"+i), Файлов, Папок);
}
}
функция ПосчитатьКаталог(sStartPath, int *nFilesCount, int *nDirsCount)
{
hFirstFile = FindFirstFile(sStartPath+"*.*", &wfd); // ищем первый
while (hFirstFile != INVALID_HANDLE_VALUE) // пока "найдено"
{
if(hFirstFile.attr&АттрибутКаталога != 0 && hFirstFile.name != "." && hFirstFile.name != "..") // если это каталог и не ссылки на себя и на предка (под DOS'ом эти условия нужны были; кстати, будет ли работать под Win без него?)
{
nDirsCount++;
ПосчитатьКаталог(sStartPath+hFirstFile.name, &nFilesCount, &nDirsCount); // рекурсия для найденного подкаталога
}
else
// если это не каталог, знач файл
nFilesCount++;
FindNextFile(hFirstFile, &wfd); // ищем следующий
};
};
Уф... Надеюсь основную мысль я выразить смог и перевести в нормальный Си у вас получится.
to All
Ногами не пинать! ;) На си не пишу уже давно... Деградировал до VBA и 1С ;)
Diseased Head
19-12-2006, 19:56
bezumes
и чем тогда "*.?*" отличается от "*.*"как чем, в первом случае расширение 1 символ а во втором любое количество. Один символ, это когда - "*.?". А маски: "*.*", "*.?*", "*.??*" и т. д. - дают идентичный результат.
aESThete
Попробую составить примерный алгоритм на "псевдо-C++" (дикой смеси си и васика). Так этож новый язык - СиВасик (Casic или C от Васи). :grin:
На си не пишу уже давно... Деградировал до VBA и 1С Деградация это плохо... :)
Всё нормально... Без обид aESThete... :joke:
aESThete
20-12-2006, 08:19
Diseased Head
"*.*", "*.?*", "*.??*" и т. д. - дают идентичный результат.
Не совсем относится к теме, но позвольте не согласиться:
"*.*" - расширение любое (может и пустое)
"*.?*" - расширение не пустое (не менее 1 символа)
"*.??*" - соответственно не менее 2 символов
Diseased Head
20-12-2006, 17:13
aESThete, в коммандной строке Win XP (да и в DOS'е), получаем:
dir *,*, dir *,?* и dir *,??* - выводятся все файлы и папки (с расширением и без).
dir *.? - выводятся файлы и папки, с расширением в один символ и без расширения (не более одного символа).
Из книжки В. Э. Фигурнов "IBM PC для пользователя": Символ ? обозначает один произвольный символ или отсутствие символа в имени файла или в расширении имени файла.
Так что ты не прав. К сожалению - НЕ МЕНЕЕ нельзя зделать.
Все-равно, даже когда я поставил *.* чтобы все посчитать, он мне как-то неправильно считает. Например в корне диска d у меня на два
меньше чем он считает, а на с всего шесть, а он считает 18.
char temp[100];
for(int i=0;i<26;i++)
{
hFirstFile=0;
WIN32_FIND_DATA FindFileData;
HANDLE hf;
if(i==2)
{
m_info += " В корне диска C ";
hf=FindFirstFile("c:\\*.*", &FindFileData);
//hFirstFile++;
}
else
if(i==3)
{
m_info += " В корне диска D ";
hf=FindFirstFile("d:\\*.*", &FindFileData);
//hFirstFile++;
}
else
{
hf=FindFirstFile("e:\\*", &FindFileData);
}
if (hf!=INVALID_HANDLE_VALUE)
{
do
{
hFirstFile++;
}
while (FindNextFile(hf,&FindFileData)!=0);
itoa( (int)hFirstFile, temp, 10 );
m_info += (CString)&temp[0]; m_info += " Файлов и папок";m_info += "\r\n";
FindClose(hf);
}
}
UpdateData(false);
aESThete, в коммандной строке Win XP (да и в DOS'е), получаем:
dir *,*, dir *,?* и dir *,??* - выводятся все файлы и папки (с расширением и без).
dir *.? - выводятся файлы и папки, с расширением в один символ и без расширения (не более одного символа).
Из книжки В. Э. Фигурнов "IBM PC для пользователя": Символ ? обозначает один произвольный символ или отсутствие символа в имени файла или в расширении имени файла.
Так что ты не прав. К сожалению - НЕ МЕНЕЕ нельзя зделать.
А почему тогда, например в стандартном xp поиске *.* это все файлы *.?* файлы с расширением более 1 символа
Diseased Head
21-12-2006, 19:32
bezumes
А почему тогда, например в стандартном xp поиске *.* это все файлы *.?* файлы с расширением более 1 символа Проверил - действительно не более одного символа (я поиском редко пользуюсь). А почему это? Да потому что: программеры в Microsoft напортачили с этим поиском (так как DOS раньше был, и коммандная строка, почему-то, иначе работает). Это, думаю, одна из причин глюков... Или это издёвка над пользователями - что-б жизнь малиной не казалась.
Vovchick1
22-12-2006, 01:43
Все-равно, даже когда я поставил *.* чтобы все посчитать, он мне как-то неправильно считает. Например в корне диска d у меня на два меньше чем он считает, а на с всего шесть, а он считает 18.
1. Может скрытые или системные не отображаются.
2. Может переменную "счётчика" не обнулил до начала циклов, и вней присутствуют левые данные.
Например в корне диска d у меня на два меньше чем он считает
3. Не вкурсе насчёт этих функций, но когда ищеш файлы по маске (стандартными средствами Pascal или VB) обычно первые два "файла": ".."
И "..." (Или что-то в этом роде, уже непомню).
aESThete
22-12-2006, 08:43
Vovchick1
см. мой исходник: (hFirstFile.name != "." && hFirstFile.name != "..")
это ссылки на себя и на предка (но откуда они в корне?!)
прекрасно видно, если смотреть каталог DiskEdit'ом
Diseased Head
программеры в Microsoft напортачили с этим поиском
это точно, с отдельно стоящим(и) "?" глючок-с
для пробы создал
readme.
readme.t
readme.tx
readme.txt
под XP dir *.*, *.?* и т.д. дают одинаковы е результаты
но read?me (файлов не найдено) и read*me (файлы найдены) отрабатывает чётко
Vovchick1
22-12-2006, 11:00
aESThete
см. мой исходник: (hFirstFile.name != "." && hFirstFile.name != "..")
Пардон виноват незаметил!!! :)
это ссылки на себя и на предка (но откуда они в корне?!)
Насчёт ".." вкурсе, а что за "." незнал, будем знать!!! :)
прекрасно видно, если смотреть каталог DiskEdit'ом
Это ты про:
Может скрытые или системные не отображаются.
А насчёт:
Может переменную "счётчика" не обнулил до начала циклов, и вней присутствуют левые данные.
Может переменную "счётчика" не обнулил до начала циклов, и вней присутствуют левые данные.
Сам счетчик в начале цикла for обнуляется. возможно надо HANDLE hf обнулить. Я попробывал написать hf=INVALID_HANDLE_VALUE; и у меня вообще отрицательные значения получились. хотя если в конце стоит FindClose(hf); то этого не надо делать
CString bukva[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y ','z'};
char temp[100];
for(int i=0;i<26;i++)
{
hFirstFile=0;//обнуляем
hFirstFile=0; // и здесь обнуляем
WIN32_FIND_DATA lpFindFileData ;
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf=INVALID_HANDLE_VALUE;
hf=FindFirstFile(_T(bukva[i]+":\\*.*"), &FindFileData);
if (hf!=INVALID_HANDLE_VALUE)
{
do
{hFirstFile=0;hFirstFile=0;
if ((FindFileData.dwFileAttributes&&FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
{
hFirstFile++;
}
else
{
hFirstFile1++;
}
}
while (FindNextFile(hf,&FindFileData)!=0);
m_info += " В корне диска "+_T(bukva[i]+" ");
itoa( (int)hFirstFile, temp, 10 );
m_info += (CString)&temp[0]; m_info += "папок";m_info += "\r\n";
m_info += " В корне диска "+_T(bukva[i]+" ");
itoa( (int)hFirstFile1, temp, 10 );
m_info += (CString)&temp[0]; m_info += " файлов";m_info += "\r\n";
FindClose(hf);
}
}
UpdateData(false);
В итоге получилось вот так:только долговато ищет(у меня 14.19 сек, а что будет на более слабых компах:) ), ну и результаты от стандартного поиска отличаются(но немного)
Find(CString(bukva[i])+CString(":"));
void CSysInfoDlg::Find(CString szPath)
{
CFileFind F;
CString S=szPath+"\\*.*";
BOOL bFlag=F.FindFile(S);
while(bFlag)
{
bFlag=F.FindNextFile();
if(F.IsDirectory()==TRUE && F.IsDots()==FALSE)
{
p++;
Find(F.GetFilePath());
}
else
{
f++;
}
}
F.Close();
}
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.