Как я могу получить FindFirstFile для сортировки файлов - PullRequest
5 голосов
/ 14 марта 2009

Я использую стандартные FindFirst и FindNext для извлечения всех файлов в каталоге но мне нужно, чтобы результаты возвращались отсортированными (в том же порядке, в котором щелчок по столбцу имени в проводнике сортировал их в основном) Как я могу достичь этого Это должно быть сделано через Win32 Спасибо

Ответы [ 6 ]

10 голосов
/ 14 марта 2009

Для этого можно использовать Службу индексирования , но я бы порекомендовал просто выполнить сортировку самостоятельно при использовании FindFirstFile.

Сортировка невозможна с помощью FindFirstFile Win32 API. Есть немного более продвинутый FindFirstFileEx , но даже это не позволяет сортировать.

Рэймонд Чен опубликовал пост в The Old New Thing об ограничениях FindFirstFile .

Лучше всего загружать все результаты в вектор, а затем сортировать их.

6 голосов
/ 15 марта 2009

Как все отметили, FindFirstFile() не сортирует и не может отсортировать возвращаемые файлы. Он работает на довольно низком уровне и возвращает файлы в порядке, который соответствует естественному порядку записей файловой системы в каталоге.

На диске, отформатированном с использованием файлов FAT и FAT32, этот порядок будет сильно зависеть от порядка, в котором файлы были созданы, изменены путем удаления файлов и возможного повторного использования теперь пустых слотов записей каталога. Это связано с тем, что каталоги FAT (как и во многих файловых системах Unix) представляют собой просто упакованный массив структур записей каталога фиксированного размера вместе с уродливым хаком для размещения длинных имен файлов, написанных в Unicode, в структуре каталогов, предназначенной для имен 8.3, написанных в ASCII. В отличие от Unix, вызовы Win32 API необходимы для чтения записей каталога, но это не влияет на порядок чтения записей.

В NTFS (насколько я понимаю) каталоги представлены в некотором варианте B-дерева, и поэтому естественный порядок файлов, видимый Win32 API, связан с индексированием, естественным для этой структуры данных.

Различия можно увидеть с помощью команды DIR в командной строке. На томе FAT32 DIR показывает файлы в другом порядке, чем если бы эта же папка была скопирована на том NTFS. DIR /ON должен перечислять файлы в том же порядке независимо от используемой базовой файловой системы.

Ни один не отсортированный порядок, созданный DIR, не совпадает с порядком, созданным в проводнике Windows при сортировке по имени. (Впрочем, DIR /ON тоже не то же самое.)

Проводник Windows использует независимую от регистра сортировку, которая также, похоже, игнорирует некоторые знаки препинания в сортировке и пытается быть умнее с числами. В частности, простое использование qsort() с stricmp() не даст тот же ответ, что и Explorer. Неясно, задокументирован ли где-либо фактический порядок сортировки, используемый проводником или DIR.

Например, следующие имена сортируются в DIR следующим образом:

C:\temp\test> dir/on/b
aoli.txt
a-one.txt
atwo.txt
b1.txt
b10.txt
b2.txt
b-20.txt
b21.txt
b3.txt
b-4.txt

но транскрибируя из Проводника, отсортированного в столбце Имя, они в следующем порядке:

aoli.txt
a-one.txt
atwo.txt
b1.txt
b2.txt
b3.txt
b10.txt
b21.txt
b-4.txt
b-20.txt

У меня проблемы с представлением простого применения функции сравнения для получения последнего эффекта.

3 голосов
/ 19 мая 2011

вы можете легко отсортировать имена файлов, поместив их в std :: set следующим образом:

std::string FileName;
std::set<string> ListOfFileNames;

WIN32_FIND_DATAA findFileData;
HANDLE MyHandle = FindFirstFileA("*.*",&findFileData);

if( MyHandle != INVALID_HANDLE_VALUE)
{
    FileName = findFileData.cFileName;
    ListOfFileNames.insert(FileName);

    while(FindNextFileA(MyHandle,&findFileData) != 0)
    {
        FileName = findFileData.cFileName;
        ListOfFileNames.insert( FileName );
    }
}

FindClose(MyHandle);

// Output the list of names found
for(std::set<string>::iterator Name = ListOfFileNames.begin() ; Name != ListOfFileNames.end() ; ++Name)
{
    cout << *Name << endl;
}
2 голосов
/ 14 марта 2009

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

0 голосов
/ 08 ноября 2018

Windows имеет API для этой конкретной ситуации. Например. Вы можете использовать CompareString, и он составляет hyphens/numbering/etc, как Explorer, я думаю, по умолчанию (flags = 0)

0 голосов
/ 14 марта 2009

Win32

Сначала используйте findfirst и findnext, чтобы найти все файлы (помните, findfirst и findnext поддерживают glob'ing (* .exe и т. Д.) ... Загрузите подходящие файлы в список и отсортируйте его. STL поможет вам есть.

Linux

Используйте opendir () и readdir (), чтобы найти все файлы в каталоге. Используйте fnmatch () для этих файлов, чтобы сделать ваш глобус. И точно так же, как Windows, загрузите соответствующие файлы в список и отсортируйте его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...