How to determine file and tree sizes larger 2 GB (Views: 300)
Problem/Question/Abstract: How to determine file and tree sizes larger 2 GB Answer: Solve 1: You will need to use the FindFirstFile, FindNextFile and FindClose functions, e.g.: function GetFileSize(const FileName: string): Int64; var F: TWin32FindData; H: THandle; begin H := FindFirstFile(PChar(FileName), F); if H = INVALID_HANDLE_VALUE then RaiseLastWin32Error; try Result := F.nFileSizeHigh shl 32 + F.nFileSizeLow; finally Windows.FindClose(H); end; end; function GetTreeSize(FileName: string): Int64; procedure TreeSize(const FileName: string); var F: TWin32FindData; H: THandle; begin H := FindFirstFile(PChar(FileName), F); if H = INVALID_HANDLE_VALUE then RaiseLastWin32Error; try repeat if ((F.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) > 0) and (F.cFileName[0] <> '.') then TreeSize(ExtractFilePath(FileName) + F.cFileName + '\*.*') else Result := Result + F.nFileSizeHigh shl 32 + F.nFileSizeLow; until not FindNextFile(H, F); finally Windows.FindClose(H); end; end; begin Result := 0; TreeSize(IncludeTrailingBackslash(ExtractFilePath(FileName)) + '*.*'); end; I would add one little detail to your function. By calculating the filesize, you should cast the values to Int64. In the helpfile you can read, that this is necessary, because the operation would normally return an integer. In this case, (F.nFileSizeHigh shl 32) would return an Integer and not an Int64. Result := Int64(F.nFileSizeHigh) shl 32 + Int64(F.nFileSizeLow); I think, casting "nFileSizeLow" is not necessary, but better to make it safe. Solve 2: Use the WinAPI version of the function GetFileSize() as follows: procedure CardinalsToI64(var I: Int64; const LowPart, HighPart: Cardinal); begin TULargeInteger(I).LowPart := LowPart; TULargeInteger(I).HighPart := HighPart; end; { ... } var fLOdword: dword; fHIdword: dword; FFilesize: Int64; FFileHandle: THandle; begin FFileHandle := CreateFile(PChar(FFileName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); fLOdword := GetFileSize(FFileHandle, @fHIdword); CardinalsToI64(FFilesize, fLOdword, fHIdword); |