2017-06-13 51 views
0

我想排序基於規模在2010年德爾福的文件列表排序文件 我遞歸把所有文件大小,文件創建日期和文件位置路徑,但我有一個問題排序他們。德爾福 - 根據大小

我的結果是這樣的:

MB 57.682(60483584) - 2017年8月6日15:03 - O:\的Thumbs.db

MB 4.217(4422144) - 2017年8月6日13:48 - O:\ BMP \的Thumbs.db

的數據必須進行排序從最大的文件下降到最小的文件並保存到一個文件中的結果。

我使用字符串格式化文件的大小爲人類可讀的形式。

什麼是在這種情況下,正確的做法? 我應該將數據存儲爲csv值,然後嘗試對它們進行排序嗎? 我應該使用字符串列表嗎?

這是我使用的代碼:

procedure FasterSubFilesList_mmg(folder, exts: string; files: TStrings); 

// builds recursive list of files matching set of extensions like '.exe .txt.htm' 
function ext(filename: string): string; 
    begin result:= lowercase(extractFileExt(filename)); 
end; 

CONST 
    SizeUnits  : ARRAY[0..8] OF PChar = ('bytes','KB','MB','GB','TB','PB','EB','ZB','YB'); 

FUNCTION FormatByteSize(Size : UInt64 ; Decimals : BYTE) : String; OVERLOAD; 
    VAR 
    I   : Cardinal; 
    S   : Extended; 

    BEGIN 
    S:=Size; 
    FOR I:=LOW(SizeUnits) TO HIGH(SizeUnits) DO BEGIN 
     IF S<1024.0 THEN BEGIN 
     IF I=LOW(SizeUnits) THEN Decimals:=0; 
     Result:=Format('%.'+IntToStr(Decimals)+'f',[S]); 
     {adaug dimensiune urmata de unitatea de masura} 
     //Result:=Result+' '+StrPas(SizeUnits[I]); 

     {adaug unitatea de masura urmata de dimensiune} 
     Result:=StrPas(SizeUnits[I])+' '+Result; 
     EXIT 
     END; 
     S:=S/1024.0 
    END 
    END; 

FUNCTION FormatByteSize(Size : UInt64) : String; OVERLOAD; 
    VAR 
    P : Integer; 

    BEGIN 
    Result:=FormatByteSize(Size,3); 
    IF Size>=1024 THEN BEGIN 
     P:=PRED(LastDelimiter(' ',Result)); 
     WHILE COPY(Result,P,1)='0' DO BEGIN 
     DELETE(Result,P,1); 
     DEC(P) 
     END; 
     IF CharInSet(Result[P],['.',',']) THEN DELETE(Result,P,1) 
    END 
    END; 




{ functie pentru a afla dimensiunea unui fisier } 
function GetFileSize_mmg(const FileName: string): Int64; 
var 
    fad: TWin32FileAttributeData; 
begin 
if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad) then RaiseLastOSError; 
    //GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad); 
    Int64Rec(Result).Lo := fad.nFileSizeLow; 
    Int64Rec(Result).Hi := fad.nFileSizeHigh; 
end; 

procedure AddFolder(dir: string); 
    var F: TSearchRec; 
     size:string; 
     data_creare_fisier:string; 
    const 
    //findTypes=faArchive+faHidden+faReadOnly+faAnyFile+faDirectory; 
    findTypes=faAnyFile; 
    begin 
    dir:= excludetrailingbackslash(dir)+'\'; 

    if FindFirst(dir+'*.*', findTypes, F)=0 then 
    try 

    repeat 
    if (F.attr and faDirectory=faDirectory) then 
    begin 
     if (F.Name<>'.') and (F.Name<>'..') then AddFolder(dir+F.Name); 

    end 
    else 
    if (exts='*') or (pos(ext(F.Name)+' ', exts)>0) then 
    size:=FormatByteSize(GetFileSize_mmg(dir+F.name)); 
    shortdateformat:='dd-mm-yyyy'; 
    data_creare_fisier:=formatdatetime(shortdateformat+' hh:nn',filedatetodatetime(f.time)); 

    files.Add(size+' ('+inttostr(GetFileSize_mmg(dir+F.name))+') - '+data_creare_fisier+' - '+dir+F.Name); 
    //files.Add('"'+size+'","'+inttostr(GetFileSize_mmg(dir+F.name))+'","'+data_creare_fisier+'","'+dir+F.Name+'"'); 
    //files.Add(inttostr(GetFileSize_mmg(dir+F.name))+' ('+size+') - '+data_creare_fisier+' - '+dir+F.Name); 
    until FindNext(F)<>0; 
    finally FindClose(F) end; 
    end; 


begin 


if (trim(exts)='') or (exts='*') or (exts='*.*') then exts:='*' 
    else exts:= trim(lowercase(exts))+' '; 
files.clear; 
AddFolder(folder); 
end; 



procedure TForm1.Button1Click(Sender: TObject); 
var 
    FilesList: TStringList; 
i:integer; 
    lista_descrescatoare:Tstrings; 
begin 
ListBox_fisiere_de_verificat.Items.Clear; 


//listbox_fisiere_de_verificat.Items.BeginUpdate; 
//afiseaza_in_listbox_fisiere_ce_pot_fi_procesate('O:\','*.*',true,10,listbox_fisiere_de_verificat,false,memo_loguri); 
//listbox_fisiere_de_verificat.Items.EndUpdate; 
memo_loguri.lines.add(FormatDatetime('dd-mm-yyyy hh:mm:ss', Now) +' - start listare fisiere'); 
FilesList:=Tstringlist.Create; 
FilesList.Sorted:=true; 
FilesList.Sort; 



FasterSubFilesList_mmg('o:\','*.*',FilesList); 

listbox_fisiere_de_verificat.items.AddStrings(FilesList); 

memo_loguri.lines.add(' - total fisiere:'+inttostr(fileslist.count)); 
memo_loguri.lines.add(FormatDatetime('dd-mm-yyyy hh:mm:ss', Now) +' - stop listare fisiere'); 

end; 

謝謝!

+0

這取決於。如果你想保存它,存儲它(更好的是在像SQLite這樣的輕量級數據庫中)。如果你不這樣做,請將它分類到內存集合中,而不是在視覺控制中。 – Victoria

+0

我認爲這個問題真的取決於你在哪裏存儲你的輸出,還是僅僅關於在視覺控件中排序? – Fero

+0

我已更新我的問題。我需要將數據分類並將它們保存到文件中。 – user2858981

回答

2

考慮到你已經有你在FilesList TStringList中的文件列表,你可以對它們進行排序那裏。您可以調用CustomSort方法,提供自定義比較函數以指示哪個文件比另一個文件大。

function FileGreater(FileList: TStringList; Index1: integer; Index2: integer): integer; 
var IniPos1, EndPos1, IniPos2, EndPos2: integer; 
    Size1, Size2: Int64; 
begin 
    IniPos1 := Pos('(', FileList[Index1]) + 1; 
    EndPos1 := Pos(')', FileList[Index1]) - 1; 
    IniPos2 := Pos('(', FileList[Index2]) + 1; 
    EndPos2 := Pos(')', FileList[Index2]) - 1; 

    Size1 := StrToint64(Copy(FileList[Index1], IniPos1, EndPos1 - IniPos1)); 
    Size2 := StrToint64(Copy(FileList[Index2], IniPos2, EndPos2 - IniPos2)); 

    if Size1 = Size2 then Result := 0 
    else if Size1 < Size2 then Result := -1 
    else Result := 1; 
end; 

現在您只要致電:

FileList.CustomSort(FileGreater);  

PS:由於大衛赫弗南在評論說,StrToInt返回LONGINT,所以這將只對文件的工作可達2GB。我已經更新了使用StrToInt64的答案,但使用適當的結構來存儲文件的數據會更好,而不是使用此快速修復。

+2

TStringList.CustomSort呢? –

+0

我不知道那種方法。是的,它更容易。 :-)。我將編輯答案。謝謝。 –

+0

TStringList.CustomSort肯定會更容易和更快 – Fero