如何让FindFirstFile对文件进行排序

时间:2009-03-14 20:31:34

标签: c++ c winapi

我使用标准FindFirstFindNext来检索目录中的所有文件 但我需要将结果重新排序(按照在资源管理器中单击名称列的顺序相同的顺序排序) 我怎么能得到这个 这必须通过Win32完成 谢谢

6 个答案:

答案 0 :(得分:10)

您可以使用Indexing Service,但我建议您在使用FindFirstFile时自行处理排序。

使用FindFirstFile Win32 API无法进行排序。有一个稍高级FindFirstFileEx,但即使这样也不允许排序。

有一个Raymond Chen post on The Old New Thing about FindFirstFile's limitations

您最好的选择可能是将所有结果加载到矢量中,然后对其进行排序。

答案 1 :(得分:6)

正如大家所指出的那样,FindFirstFile()没有,也无法对它返回的文件进行排序。它的运行水平相当低,并按照与文件系统目录条目的自然顺序相关的顺序返回文件。

在使用FAT和FAT32格式化的磁盘上,该顺序将与创建文件的顺序密切相关,通过文件删除和可能重新使用现在空的目录条目槽来修改。这是因为FAT目录(就像在许多unix文件系统上一样)只是一个固定大小的目录条目结构的打包数组,以及一个丑陋的黑客,用于将用Unicode编写的长文件名拟合到为ASCII编写的8.3名称设计的目录结构中。与Unix不同,需要Win32 API调用来读取目录条目,但这不会影响条目的读取顺序。

在NTFS上(据我所知),目录在B-Tree的某个变体中表示,因此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

我很难想象在比较函数中应用简单来获得后一种效果。

答案 2 :(得分:3)

您可以通过将文件名放入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;
}

答案 3 :(得分:2)

您需要将所有文件名读取到一些合适的集合中,然后自己对它们进行排序。 Windows API不提供任何排序​​功能。

答案 4 :(得分:0)

的Win32

首先,使用findfirst和findnext查找所有文件(记住,findfirst和findnext支持glob'ing(* .exe等)...将匹配的文件加载到列表中并对其进行排序.STL将帮助您那里。

Linux的

使用opendir()和readdir()查找目录中的所有文件。对这些文件使用fnmatch()来进行全局化。就像Windows一样,将匹配的文件加载到列表中并对其进行排序。

答案 5 :(得分:0)

Windows确实有针对这种情况的API。例如。您可以使用 CompareString ,它像资源管理器一样解释连字符/编号/等,我相信默认情况下( flags = 0

相关问题