ne_viens
Advanced Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору #ifndef UNICODE #define UNICODE //так как ожидаем не английские названия файлов тоже, включаем unicode кодировку #endif #ifndef _UNICODE #define _UNICODE #endif #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #pragma optimize("s", on) //для удобства отладки на OllyDbg #define NUM_MAX 500000 //max ожидаемое количество файлов, но предусмотрен механизм динамического увеличения max количества записей typedef struct { //тут будем хранить указатели на названия файлов, текущее положение в массиве, объём массива int count; int max; short* entries; } PACK; void find_files(wchar_t* wrkdir, PACK** ptr) //рекурсивная ф-я поиска файлов { int i; PACK *p, *newPack; HANDLE hFile; WIN32_FIND_DATA file_data; wchar_t wrkdirtemp[MAX_PATH], buf[MAX_PATH], buf2[MAX_PATH]; if(!wrkdir || !wrkdir[0]) //проверка аргумента (рабочая директория) на пригодность к дальнейшей работе return; wcscpy(wrkdirtemp, wrkdir); //делаем копию для работы if(wrkdirtemp[wcslen(wrkdirtemp)-1] != L'\\') //если нет, добавляем "\" wcscat(wrkdirtemp, L"\\"); wsprintf(buf, L"%s*", wrkdirtemp); //добавляем "*", если надо что-то другое, можно передать через третий аргумент hFile = FindFirstFile(buf, &file_data); //начинаем пойск if(hFile == INVALID_HANDLE_VALUE) return; do //основная петля поиска { if(file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) //если попали на директорию... { // if(wcscmp(file_data.cFileName, L".") && wcscmp(file_data.cFileName, L"..")) //..проверяем не текущая или родительская ли if('.' == *(int*)&file_data.cFileName || (0x002e002e == *(int*)&file_data.cFileName && 0 == *(short*)((char*)file_data.cFileName + 4))) //то-же, только быстрее continue; //если "." или "..", пропускаем wsprintf(buf, L"%s%s", wrkdirtemp, file_data.cFileName); //иначе добавляем к рабочей копии директории find_files(buf, ptr); //и уходим в нее рекурсивно } else //если на файл попали... { // if(!(file_data.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))) //и он не скрытый и не системный // wprintf(L"%s%s\n", wrkdirtemp, file_data.cFileName); //печатаем p = *ptr; //указатель на структуру if(p->count >= p->max) //есть место ещё? { i = p->max * 2; //нет, делаем размер 2 раза больше newPack = malloc(i * sizeof(void*) + sizeof(int) * 2); //выделяем память под новую структуру newPack->max = i; //переносим туда всё с старой переполненной newPack->count = p->count; memcpy(&newPack->entries, &p->entries, p->count * sizeof(void*)); free(p); //и удаляем старую p = newPack; //правим указатели на новую структуру чтобы указывали *ptr = newPack; } i = wsprintf(buf2, L"%s%s\n", wrkdirtemp, file_data.cFileName); //формируем "path"+"filename", получаем его длину *(&p->entries + p->count) = malloc((i + 1) * 2); //выделяем для него память, указатель на которую сохраняем в текущее положение массива memcpy(*(&p->entries + p->count), buf2, (i + 1) * 2); //и копируем в эту память "path"+"filename" ++p->count; //инкрементируем указатель на текущее положение в массиве } } while (FindNextFile(hFile, &file_data)); //и так далее, пока все файлы в текущей директории не найдены FindClose(hFile); } main() { int i; PACK* p; p = malloc(NUM_MAX * sizeof(void*) + sizeof(int) * 2); //выделяем память под структуру указателей названий файлов p->count = 0; //инициализируем указатель на текущее положение в массиве p->max = NUM_MAX; //и размер массива find_files(L"C:", &p); //заполняем структуру find_files(L"Z:", &p); // sort_files(&p); //если надо, сортируем _setmode(_fileno(stdout), _O_U16TEXT); //подготавливаем печать в unicode, чтобы не английские названия тоже печатались for(i = 0; i < p->count; ++i) { wprintf(L"%s", *(&p->entries + i)); //печатаем из массива free(*(&p->entries + i)); //и освобождаем память элемента массива } free(p); //удаляем структуру } | Всего записей: 1530 | Зарегистр. 01-11-2004 | Отправлено: 18:22 16-02-2013 | Исправлено: ne_viens, 15:03 03-03-2013 |
|