列出目录中的文件名并进行排序?

时间:2011-12-28 21:54:02

标签: delphi

  

可能重复:
  How to get the sort order in Delphi as in Windows Explorer?

我正在尝试扫描一个目录,但我无法按照文件名排序。

示例,假如我在文件夹中有这些文件名:

  
      
  • File1中
  •   
  • 文件2
  •   
  • 文件3
  •   
  • FILE4
  •   
  • File5
  •   
  • File6
  •   
  • File7
  •   
  • File8
  •   
  • File9
  •   
  • File10
  •   
  • FILE11
  •   
  • File12
  •   
  • File13
  •   
  • FILE14
  •   
  • File15
  •   
  • File16
  •   
  • File17
  •   
  • File18
  •   
  • File19
  •   
  • File20
  •   
  • File21
  •   
  • File22
  •   

如果我使用这样的东西:

var
  SL: TStringList;
  SR: TSearchRec;  
begin
  SL := TStringList.Create;
  try
    if FindFirst(Path + '*.*', faAnyFile and not faDirectory and not faHidden, SR) = 0 then
    repeat
      SL.Add(Path + SR.Name)
    until FindNext(SR) <> 0;

    FindClose(SR);

    // handle the filenames..
  finally
    SL.Free;
  end;
end;

结果将是:

  
      
  • File10
  •   
  • FILE11
  •   
  • File12
  •   
  • File13
  •   
  • FILE14
  •   
  • File15
  •   
  • File16
  •   
  • File17
  •   
  • File18
  •   
  • File19
  •   
  • 文件2
  •   
  • File20
  •   
  • File21
  •   
  • File22
  •   
  • 文件3
  •   
  • FILE4
  •   
  • File5
  •   
  • File6
  •   
  • File7
  •   
  • File8
  •   
  • File9
  •   

它应按Filename排序(正如我在第一个文件名列表示例中所写的那样)。

我敢打赌,这很简单,但我看不清楚,我需要做些什么才能对此进行排序?

感谢。

3 个答案:

答案 0 :(得分:7)

您首先假设文件名存在某种固有的“顺序”。没有。您似乎希望按字母顺序对文件名进行排序,名称的数字部分按数字顺序排序。我不确定你想要用标点符号和其他字符发生什么。

文件枚举函数没有定义任何将返回名称的顺序。它们以基础文件系统决定提供它们的任何顺序返回。获取文件名的排序列表有两个步骤。你已经在做第一个了:

  1. 在列表中收集文件名以进行后处理。

  2. 按照您想要的顺序排列名称。如果简单的“asciibetical”不是您想要的,那么您可以编写自定义排序函数并将其传递给TStringList.CustomSort

  3. 例如,如果您希望它们的顺序与Windows XP中Windows资源管理器中的文件名相同,则可以使用StrCmpLogicalW API函数。从比较函数中调用,如下所示:

    function LogicalCompare(List: TStringList; Index1, Index2: Integer): Integer;
    begin
      Result := StrCmpLogicalW(PWideChar(List[Index1]), PWideChar(List[Index2]));
    end;
    
    SL.CustomSort(LogicalCompare);
    

    如果你有比Delphi 2007更早的东西,你需要做一些关于将字符串转换为宽字符的事情,至少在分类阶段是这样。

答案 1 :(得分:3)

FindFirst()FindNext()只是按原样枚举文件系统上的文件。可以按任何顺序返回文件。您必须事后对TStringList进行排序,例如:

function SortFilesByName(List: TStringList; Index1, Index2: Integer): Integer;
var
  FileName1, FileName2: String;
  FileNumber1, FileNumber2: Integer;
begin
  // assuming the files are all named "Path\File###.xxx",
  // where "###" is the number to sort on...
  FileName1 := ChangeFileExt(ExtractFileName(List[Index1]), '');
  FileName2 := ChangeFileExt(ExtractFileName(List[Index1]), '');
  FileNumber1 := StrToInt(Copy(FileName1, 5, MaxInt));
  FileNumber2 := StrToInt(Copy(FileName2, 5, MaxInt));
  Result := (FileNumber2 - FileNumber1);
end;

var 
  SL: TStringList; 
  SR: TSearchRec;   
begin 
  SL := TStringList.Create; 
  try 
    if FindFirst(Path + '*.*', faAnyFile and (not faDirectory) and (not faHidden), SR) = 0 then 
    try
      repeat 
        SL.Add(Path + SR.Name) 
      until FindNext(SR) <> 0; 
    finally
      FindClose(SR); 
    end;

    SL.CustomSort(SortFilesByName);
    // handle the filenames.. 
  finally 
    SL.Free; 
  end; 
end; 

答案 2 :(得分:0)

任何简单的排序系统(例如一个窗口用于返回文件和delphi用于排序)将按字母顺序排序,然后按数字排序,但除非用零填充数字

  • 1来自2之前
  • 11出现在2之前(与b之前的aa相同)

你需要用零填充数字,例如

  • filename001
  • filename010
  • filename020

使用上面Remy Lebeau - TeamB提供的答案,该答案会提取您文件名末尾的数字并按其排序。