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