Rozmiar plików i katalogów

0

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

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?

1 użytkowników online, w tym zalogowanych: 0, gości: 1