It should be easy, but I can’t get it right, because I seem to be confusing myself and converting to and from strings, integers and floats and much more.
Basically, I populate a TListView with the names FileNames in one column, and in the other column it returns the file size to the corresponding file_name. I use a pretty neat feature from here that looks like this:
function FileSizeStr ( filename: string ): string; const // K = Int64(1000); // Comment out this line OR K = Int64(1024); // Comment out this line M = K * K; G = K * M; T = K * G; var size: Int64; handle: integer; begin handle := FileOpen(filename, fmOpenRead); if handle = -1 then result := 'Unable to open file ' + filename else try size := FileSeek ( handle, Int64(0), 2 ); if size < K then result := Format ( '%d bytes', [size] ) else if size < M then result := Format ( '%f KB', [size / K] ) else if size < G then result := Format ( '%f MB', [size / M] ) else if size < T then result := Format ( '%f GB', [size / G] ) else result := Format ( '%f TB', [size / T] ); finally FileClose ( handle ); end; end;
This returns values such as: 235.40 KB
So, with the above, my TListView can be populated like this:
Now, in the size of the label data, I would like to return the total size of the files in the Listview, so in this example, the values from the Size column will need to be added to return the total size, for example:
1.28 MB + 313.90 KB + 541.62 KB + 270.96 KB
Obviously, it cannot be added in the same way, because the values contain decimal points, some values can be in Kb, others in Mb, etc. This is my problem, I can’t come up with a simple solution to add (receive) the total file size, and then return it to the same formatted string as shown.
I would really like understanding or advice on how to work with such data, I just endlessly confuse myself with different transformations, etc., and don’t know which way to do it.
Thank you very much in advance:)
UPDATE 1
Following Marc B's recommendations, I changed the function to the following, which seems to work:
var iFileSize: Int64; implementation function GetSizeOfFile(FileName: string): Int64; var Handle: Integer; begin Handle := FileOpen(FileName, fmOpenRead); if Handle = -1 then MessageDlg('Unable to open file ' + FileName, mtError, [mbOk], 0) else try iFileSize := iFileSize + FileSeek(Handle, Int64(0), 2); finally FileClose(Handle); end; Result := iFileSize; end; function FormatFileSize(AValue: Int64): string; const K = Int64(1024); M = K * K; G = K * M; T = K * G; begin if AValue < K then Result := Format ( '%d bytes', [AValue] ) else if AValue < M then Result := Format ( '%f KB', [AValue / K] ) else if AValue < G then Result := Format ( '%f MB', [AValue / M] ) else if AValue < T then Result := Format ( '%f GB', [AValue / G] ) else Result := Format ( '%f TB', [AValue / T] ); end;
It can be useful for someone else if they need it :)
UPDATE 2
Also, see Ken White's answer for more valuable information and a cleaner update to the GetSizeOfFile function, which works just fine: