Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to report file size in a descriptive string Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
05-Jul-03
Category
Files Operation
Language
Delphi 2.x
Views
79
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Dmitri Papichev

How to tell the file size in a descriptive string like "2.33MB", or "233 bytes", as 
Windows Explorer does in a status bar? 

Answer:

The articles of Adam Lanzafame and NYB about file size string, and follow-up 
discussions inspired me to come with a solution which would resolve some of the 
issues of both aforementioned approaches/implementations (see the DPFileSize unit 
attached below). 

Some of these issues are: 

Adam's function depends on the external library presence, specifically SHLWAPI.DLL 
(Shell Light-weight Utility Library), which is essentially a helper library and may 
not be installed on all systems. 

For files from 1000 to 1023 bytes in size both Adam's and NYB's functions return 
the size in bytes, while Windows Explorer displays '0.99KB' 

Windows Explorer doesn't add space between a number and 'KB', 'MB', and 'GB', while 
both Adam's and NYB's functions do. 

NYB's function always displays two digits after a decimal point (even for bytes), 
while the main idea of how Windows Explorer represents the number here is obviously 
to keep three significant digits, including leading zero before decimal point (see 
item 2 above)   

NYB's function rounds the resulting value to the nearest value of the least 
significant digit. The Windows Explorer approach seems to me as more consistent - 
we may accept either one of the rounding directions, but it is better to be fixed. 
The direction used by Explorer is towards lesser value of the least significant 
digit, so it consistently shows that a file is at least of indicated size. 

All these issues have been addressed in the unit below. 
1   
2   //******************************************************************************
3   //
4   // Unit Name: DPFileSize
5   // Purpose  : Functions for reporting file size with a descriptive string
6   // Author   : (c) 2001 Dmitri Papichev {Dmitri.Papichev@iname.com}
7   // Comments : Specially for www.delphi3000.com
8   //
9   //******************************************************************************
10  
11  unit DPFileSize;
12  
13  {==============================================================================}
14  interface
15  
16  const
17    KB = 1024;
18    MB = KB * KB;
19    GB = MB * KB;
20  
21    {main function}
22  function GetFileSizeString(const AFileName: string): string;
23  
24  {helper functions, surfaced here as they might be used on their own}
25  function DPGetFileSize(const AFileName: string): integer;
26  function GetSignificantDigits(const ARealNumber: double;
27    const ADigits: integer): string;
28  function FormatFileSizeValue(const AValue: integer): string;
29  
30  {==============================================================================}
31  implementation
32  uses
33    SysUtils,
34    Classes;
35  
36  {------------------------------------------------------------------------------}
37  {returns the string representing the file size for a given filename, in a way
38  similar to what Windows Explorer does}
39  
40  function GetFileSizeString(const AFileName: string): string;
41  begin
42    try
43      Result := FormatFileSizeValue(DPGetFileSize(AFileName));
44    except
45      on E: Exception do
46      begin
47        Result := E.message;
48      end; {on}
49    end; {if}
50  end; {--GetFileSizeString--}
51  
52  {------------------------------------------------------------------------------}
53  {returns file size in bytes for a given filename}
54  
55  function DPGetFileSize(const AFileName: string): integer;
56  var
57    AFileStream: TFileStream;
58  begin
59    AFileStream := TFileStream.Create(AFileName,
60      fmShareCompat or fmShareDenyNone);
61    try
62      Result := AFileStream.Size;
63    finally
64      AFileStream.Free;
65    end; {try}
66  end; {--GetFileSizeDP--}
67  
68  {------------------------------------------------------------------------------}
69  {returns first ADigits significant digits of ARealNumber,
70  with a decimal point if any}
71  
72  function GetSignificantDigits(const ARealNumber: double;
73    const ADigits: integer): string;
74  begin
75    if ADigits in [1..16] then
76    begin {that's the range of sig. digits supported}
77      Result := Format('%' +
78        IntToStr(ADigits) + '.' +
79        IntToStr(ADigits) + 'f', [ARealNumber]);
80  
81      Result := Copy(Result, 1, ADigits + 1);
82      if (Pos('.', Result) in [0, ADigits + 1]) then
83      begin
84        Result := Copy(Result, 1, ADigits);
85      end; {if}
86    end
87    else
88    begin
89      raise Exception.Create('GetSignificantDigits: ' +
90        'A number of significant digits out of range');
91    end; {if}
92  end; {--GetSignificantDigits--}
93  
94  {------------------------------------------------------------------------}
95  {converts given AValue to the string representing file size, in a way similar
96  to what Windows Explorer does}
97  
98  function FormatFileSizeValue(const AValue: integer): string;
99  begin
100   case AValue of
101     0..999:
102       begin
103         Result := IntToStr(AValue) + ' bytes';
104       end;
105     1000..(MB - 1):
106       begin
107         Result := GetSignificantDigits(AValue / KB, 3) + 'KB';
108       end;
109     MB..(GB - 1):
110       begin
111         Result := GetSignificantDigits(AValue / MB, 3) + 'MB';
112       end;
113   else
114     begin
115       Result := GetSignificantDigits(AValue / GB, 3) + 'GB';
116     end;
117   end; {case}
118 end; {--FormatFileSizeValue--}
119 
120 end.


			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC