poprawny rozmiar pliku

0

Witam

Mam takie małe pytanko co do rozmiaru plików.

Przeszukuje folder poleceniem FindFirst, FindNext i to pobierania rozmaru pliku używałem rekordu TSearchRec a w nim danej Size, jego wadą jest to iż to integer a więc pliki nieco ponad 2 GB wywalają kosmiczne wartościu.

Później postanowiłem używać TFileStream ale jego wadą jest, że nie może pobrać rozmiaru otwartego przez jakiś program pliku.

Na koniec spróbowałem czegoś takiego

function FSize(filename:string):extended;
var
FileHandle: THandle;
FileSize: LongWord;
begin

begin
FileHandle := CreateFile(PChar(filename),
GENERIC_READ,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
FileSize := GetFileSize(FileHandle, nil);
Result := FileSize;
CloseHandle(FileHandle);
end
end;</span>

ale wadą tego rozwiązania jest to, że jak jakiś plik jest otwarty/używany to przypisuje mu rozmiar ok 4 GB :( i tym sposobem folder WINDOWS ma 120 GB :)))

Znacie może jakiś sposób aby wczytać poprawny rozmiar plików, używanych lub nie??

Byłbym wdzięczny za pomoc

0

Napisałem kiedyś coś takiego, myślę że się ucieszysz:

  function GetHugeFileSize(const FileName: String): Int64;
  var
    FileHandle: THandle;
    Data: TWIN32FindData;
  begin
    Result := -1;
    FileHandle := FindFirstFile(PChar(FileName), Data);
    if FileHandle <> INVALID_HANDLE_VALUE then
      try
        Result := (Data.nFileSizeHigh * High(DWORD) + 1) + Data.nFileSizeLow;
      finally
        Windows.FindClose(FileHandle);
      end;
  end;
0

hmmm ta twoja funkcja troche mnie zastanawia mianowićie Result := -1; na samym początku to chyba dziwne rozwiązanie, z tym mi sie cały komp wiesza :-)

drugie moje pytanie w czym ta funkcja zwraca wartość pliku? bajty, kilibajty,... bo jakoś nie mogę dojść dla pliku 55 MB zwraca 4,20034573061959E16

zresztą powiem że niebardzo łapie co i jak jest tam liczone [glowa]

0

jak wywaliłem to result:=-1 to zaczą nawet działać

problem w tym że tak jak poprzednie metody wywala się przy plikach Windowsa i tak Windows zamiast mieć 2,35 GB ma 1,33 GB (wielkość katalogu licze rekurencyjnie, czyli z podkatalogami)

działa identycznie jak

function ps(filename:string):extended;
var f: TFileStream;
begin
F := TFileStream.Create(filename, fmOpenRead);
result:=F.Size; // tutaj rozmiar w bajtach
F.Free;
end;

największą zmorą tych sposobów jest plik C:\WINDOWS\TempFile jest to plik ale bez rozszerzenia i tu każda metoda jak odczyta to odczyta 4 GB a pliczek ma raptem 1 czy 2 kilibajty :-D

już sam nie kumam jak to policzyć

0
  1. Po pierwsze jeśli wyrzucisz Result := -1, to w sytuacji gdy z jakiegoś powodu nie uda się odczytać wielkości pliku, wartość zwracana przez funkcję będzie niezdefiniowana. W miejscu gdzie wywołujesz funkcję powinieneś więc wykonac sprawdzenie, np. :
 
  size := GetHugeFileSize(FileName);
  if size >= 0 then
      {..coś tam..}
    else
       Warning('nie można odczytać wielkości pliku ' + FileName);

Jeśli ci się ten sposób nie podoba, to możesz przerobić funkcję na przykład tak:

  function GetHugeFileSize(const FileName: String; var HugeSize: Int64): boolean;
  var
    FileHandle: THandle;
    Data: TWIN32FindData;
  begin
    Result := False;
    FileHandle := FindFirstFile(PChar(FileName), Data);
    if FileHandle <> INVALID_HANDLE_VALUE then
      try
        HugeSize := (Data.nFileSizeHigh * High(DWORD) + 1) + Data.nFileSizeLow;
        Result := True;
      finally
        Windows.FindClose(FileHandle);
      end;
  end;
  1. Funkcja zwraca rozmiar pliku w bajtach, a na moim komputerze nie ma problemu z odczytaniem rozmiaru jakiegokolwiek pliku w katalogu Windows, ani z np. "c:\pagefile.sys".

zresztą powiem że niebardzo łapie co i jak jest tam liczone

Jeśli nie wiesz jak ta funkcja liczy rozmiar, to przeanalizuj opis funkcji FindFirstFile na msn. Funkcję napisałem na podstawie tej dokumentacji.

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