Mega Code Archive

 
Categories / Delphi / Files
 

Get file size as a string revisited supports huge files

Title: Get file size as a string revisited - supports huge files Question: Original articles Adam Lanzafame demonstrated Win API approach: http://www.delphi3000.com/articles/article_2351.asp NYB NYB demonstrated Pascal approach: http://www.delphi3000.com/articles/article_2357.asp This article shows a Pascal approach with similar benefits to NYB's code, but supports huge files (files greater than 2 gigabytes) and simplified algorithm (IMHO). Answer: Here are a couple of easy to use functions for getting the file size and converting it to an abbreviated notation similar to Explorer. function GetHugeFileSize(const FileName: string): int64; The GetHugeFileSize function takes a Filename parameter and returns the file size as an Int64. It will give accurate results for file sizes greater than 2 GB. function BytesToAbbr(const NumBytes: Int64; const Format: string = '0.##'): string; The BytesToAbbr function takes a NumBytes parameter (Int64) and an optional Format parameter (string), and returns a string with the abbreviated byte size. The abbreviation is automatically chosen based on the NumBytes value: 0 - 1023: covert to bytes 1024 - 1048575: covert to KB 1048576 - 1073741823: convert to MB etc. The format parameter is used to determine how many decimal places of precision are desired on the output, the default is 2 places ('0.##') Examples: BytesToAbbr(25197628224) BytesToAbbr(25197628224, '0.#') BytesToAbbr(25197628224, '0.###') BytesToAbbr(25197628224, '0.####') returns string results as follows: 23.47 GB 23.5 GB 23.467 GB 23.4671 GB Using these functions together takes this form: procedure TForm1.Button1Click(Sender: TObject); begin if OpenDialog1.Execute then begin Label1.Caption := BytesToAbbr(GetHugeFileSize(OpenDialog1.FileName)); end; end; Here are the functions: function BytesToAbbr(const NumBytes: Int64; const Format: string = '0.##'): string; const KiloByte = Int64(1024); MegaByte = KiloByte * 1024; GigaByte = MegaByte * 1024; TeraByte = GigaByte * 1024; var Value: Double; Suffix: string; begin Value := 0.0; //This gets rid of compiler warning //We need this check first since Case doesn't work with //integer values 32 bits (as of D5); if NumBytes = GigaByte then begin if NumBytes Suffix := ' GB'; Value := NumBytes / GigaByte; end else begin Suffix := ' TB'; Value := NumBytes / TeraByte; end; end else //NumBytes is less than 1 GB case NumBytes of 0..KiloByte-1: begin Suffix := ' bytes'; Value := NumBytes end; KiloByte..MegaByte-1: begin Suffix := ' KB'; Value := NumBytes / KiloByte; end; MegaByte..GigaByte-1: begin Suffix := ' MB'; Value := NumBytes / MegaByte; end; end; Result := FormatFloat(Format, Value) + Suffix; end; function GetHugeFileSize(const FileName: string): int64; var FileHandle: hFile; begin FileHandle := FileOpen(FileName, fmOpenRead or fmShareDenyNone); try LARGE_INTEGER(Result).LowPart := GetFileSize (FileHandle, @LARGE_INTEGER(Result).HighPart); if LARGE_INTEGER(Result).LowPart = $FFFFFFFF then Win32Check(GetLastError = NO_ERROR); finally FileClose(FileHandle); end; end; Regards, Wayne Sherman