Ponownie wracam do ćwiczonego już na tym forum tematu " odczytywania rozmiaru plików i katalogów". Wszelkie sugestie z ubiegłych lat przestudiowałem, poprawiłem niektóre błędy, przystosowałem do różnych warunków pomiaru, stosowałem wymiennie i zamiennie różne pomysły, a i tak rezultat jest raczej niezadowalający. Odczytanie dużych plików nie stanowi problemu (powyżej 4,5 GB), pomiar wielkości większości katalogów przebiega bez zakłóceń i błędów, odczytanie rozmiaru uruchomionego pliku też jest możliwe. Niestety próba odczytania (rekurencyjnie) katalogu systemowego np. "WINDOWS" lub "DOCUMENTS AND SETTINGS" kończy się katastrofą pomiarową. Zwracane wyniki nie są nawet zbliżone do rzeczywistości. Spróbujcie jeszcze raz przećwiczyć ten temat, ponieważ są przecież ludzie, którym się to udało. Pozdrawiam jednocześnie tych, którym jeszcze chce się bawić w rozwiązywanie takich zagadek w DELPHI.
0
0
To nie zagadka Delphi, a jedynie pytania o uprawnienia do umieszczonych tam zasobów.
function GetDirSize(Path:TFileName):int64;
type Int64Record = record
case boolean of
TRUE: (Int:Int64);
FALSE: (Lo, Hi:DWORD);
end;
var Search:TSearchRec;
Handle:THandle;
Size:Int64Record;
begin
Path:=IncludeTrailingPathDelimiter(Path);
result:=0;
if (FindFirst(Path+'*', faAnyFile, Search) = 0) then
begin
repeat
if (Search.Name<>'.') and (Search.Name<>'..') then
begin
if (Search.Attr and faDirectory>0) then
result:=result+GetDirSize(Path+Search.Name)
else
begin
Handle:=CreateFile(PChar(Path+Search.Name), 0, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
if (Handle<>INVALID_HANDLE_VALUE) then
begin
Size.Lo:=GetFileSize(Handle, @Size.Hi);
result:=result+Size.Int;
CloseHandle(Handle);
end;
end;
end;
until (FindNext(Search)<>0);
FindClose(Search);
end;
end;
Ponieważ Eksplorator Windows nie dolicza do rozmiaru katalogów niektórych plików systemowych, funkcja może zwracać nieznacznie większe (rzeczywiste) wartości rozmiaru katalogów, niż podane we właściwościach folderu.
Bardziej odpowiadająca wynikom Eksploratora wersja wygląda tak:
{$WARN SYMBOL_PLATFORM OFF}
function GetFolderInfo(Path:TFileName):string;
type Int64Record = record
case boolean of
TRUE: (Int:Int64);
FALSE: (Lo, Hi:DWORD);
end;
TFullInfo = record
Files:DWORD;
Folders:DWORD;
Size:Int64Record;
end;
var Info:TFullInfo;
Size:Int64Record;
procedure GetDirSize(Path:TFileName);
var Search:TSearchRec;
begin
Path:=IncludeTrailingPathDelimiter(Path);
if (FindFirst(Path+'*', faAnyFile, Search) = 0) then
begin
repeat
if (Search.Name<>'.') and (Search.Name<>'..') then
begin
if (Search.Attr and faDirectory>0) then
begin
inc(Info.Folders);
GetDirSize(Path+Search.Name)
end
else
begin
inc(Info.Files);
Size.Lo:=Search.FindData.nFileSizeLow;
Size.Hi:=Search.FindData.nFileSizeHigh;
Info.Size.Int:=Info.Size.Int+Size.Int;
end;
end;
until (FindNext(Search)<>0);
FindClose(Search);
end;
end;
begin
ZeroMemory(@Info, sizeof(Info));
GetDirSize(Path);
result:=Format('Plików: %d, Folderów: %d, Rozmiar: %d', [Info.Files, Info.Folders, Info.Size.Int]);
end;
0
Dziękuję za podpowiedź.Procedura sprawdza się w działaniu.
0
mi ten algorytm do rozmiaru plików nie działa. podaje dobrą ścieżkę:
showmessage(inttostr(GetDirSize('C:\plik.txt')));
i zawsze wyskakuje 0.
0
sierotko, GetDirSize, jak myślisz co oznacza dir?