I am trying to write a function that returns the size of a directory. I have written the following code, but it is not returning the correct size. For example, when I run it on the {pf}
directory it returns 174 bytes, which is clearly wrong as this directory is multiple Gigabytes in size. Here is the code I have:
function GetDirSize(DirName: String): Int64;
var
FindRec: TFindRec;
begin
if FindFirst(DirName + '\*', FindRec) then
begin
try
repeat
Result := Result + (Int64(FindRec.SizeHigh) shl 32 + FindRec.SizeLow);
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end
else
begin
Result := -1;
end;
end;
I suspect that the FindFirst
function does not include subdirectories, which is why I am not getting the correct result. Therefore, how can I return the correct size of a directory i.e. including all files in all subdirectories, the same as selecting Properties on a Folder in Windows Explorer? I am using FindFirst
as the function needs to support directory sizes over 2GB.
答案 0 :(得分:1)
FindFirst
确实包含子目录,但它不会为您提供尺寸。
您必须递归到子目录并按文件计算文件总大小,类似于Inno Setup: copy folder, subfolders and files recursively in Code section。
function GetDirSize(Path: String): Int64;
var
FindRec: TFindRec;
FilePath: string;
Size: Int64;
begin
if FindFirst(Path + '\*', FindRec) then
begin
Result := 0;
try
repeat
if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
begin
FilePath := Path + '\' + FindRec.Name;
if (FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then
begin
Size := GetDirSize(FilePath);
end
else
begin
Size := Int64(FindRec.SizeHigh) shl 32 + FindRec.SizeLow;
end;
Result := Result + Size;
end;
until not FindNext(FindRec);
finally
FindClose(FindRec);
end;
end
else
begin
Log(Format('Failed to list %s', [Path]));
Result := -1;
end;
end;
对于Int64
,您需要Unicode version of Inno Setup,无论如何都要使用{{3}}。只有当您有充分理由坚持使用Ansi版本时,才能将Int64
替换为Integer
,但不得限制为2 GB。