Solved

FILES SIZE

Posted on 2003-11-22
8
754 Views
Last Modified: 2010-04-05
Hi, i was wondering if we could do thesame. in windows in the explorer you can select a file or multiple files and it displays its size in the status bar in kb and mb or gb. I was wondering if we could also do that in delphi? i am making a program with two list box the other contains files and the other will accept the file that will be added because i have a add button. What i want is to calculate for the file size of the selected  and it will compute if it will be accomodated in drive a.. please help me..
0
Comment
Question by:aerokevs
8 Comments
 
LVL 7

Expert Comment

by:jconde
ID: 9802303
Here are 2 examples that return the size of a file in bytes:

procedure TForm1.Button1Click(Sender: TObject);
var
  f1: THandle;
  f: file of Byte;
begin
//Example 1 using Delphi functions
   AssignFile(f, 'C:\file.exe');
   Reset(f);
   showmessage(inttostr(FileSize(f)));
   CloseFile(f);

//Example 2 using the Win API
   f1 := CreateFile('C:\file.exe', GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0);
   showmessage(inttostr(GetFileSize(f1, nil)));
   CloseHandle(f1);
end;
0
 
LVL 17

Expert Comment

by:geobul
ID: 9802648
Hi,

Try this (using FileListBox with multiselect set to true). Select several files and press the button:

function GetFileSize(const strFile: string): Int64;
var
  SearchRec:TSearchRec;
begin
  result := 0;
  if (FindFirst(strFile, faAnyFile, SearchRec)=0) then begin
    // File found.
    result := (Int64(SearchRec.FindData.nFileSizeHigh) shl 32) + SearchRec.FindData.nFileSizeLow;
  end;
  FindClose(SearchRec);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  Size: Int64;
begin
  Size := 0;
  if FileListBox1.SelCount > 0 then begin // there are selected files in the box
    for i := 0 to FileListBox1.Items.Count - 1 do begin // loop the box items
      if FileListBox1.Selected[i] then begin // item i is selected
        Size := Size + GetFileSize(FileListBox1.Directory + '\' + FileListBox1.Items[i]); // get the file size
      end;
    end;
  end;
  ShowMessage(IntToStr(Size)); // show the total size of the selected files
end;

Regards, Geo
0
 
LVL 17

Expert Comment

by:geobul
ID: 9802680
Forgot to say that using my example above you don't need to open the files in order to get their size. For many files this should speed up the process. One more thing: the result is in bytes. Depending on the volume of the result you may display it in KB, MB or GB dividing it by 1024 several times (once for for KB, etc.).
0
 
LVL 11

Expert Comment

by:ZhaawZ
ID: 9803743
another version:

function GetFileSize(filename : string) : string;
var
  f : file;
  n : real;
  u : string;
begin
AssignFile(f,filename);
FileMode := 0;
Reset(f,1);
n := FileSize(f);
CloseFile(f);
u := 'B';
if n >= 1024 then begin n := n / 1024; u := 'KB'; end;
if n >= 1024 then begin n := n / 1024; u := 'MB'; end;
if n >= 1024 then begin n := n / 1024; u := 'GB'; end;
if n >= 1024 then begin n := n / 1024; u := 'TB'; end;
Result := Format('%.2f %s',[n,u]);
end;
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:aerokevs
ID: 9804700
Geobul,
     i go an incompatible type when dividing it to 1024 many times. and the  example of ZhaawZ displays a different size form the explorer it automatically round the file size.
0
 
LVL 11

Accepted Solution

by:
ZhaawZ earned 125 total points
ID: 9805244
another version (should be faster than previous, also more similar to explorer)

function GetFileSize(filename : string) : string;
var
  f : file;
  n : integer;
begin
AssignFile(f,filename);
FileMode := 0;
Reset(f,1);
n := FileSize(f);
CloseFile(f);
case n of
  0..1023 : result := format('%d bytes',[n]);   //up to 1 KB,   returns 'x bytes'
  1024..10239 : result := format('%.2f KB',[n/1024]);   //up to 10 KB,  returns 'x.xx KB'
  10240..102399 : result := format('%.1f KB',[n/1024]);   //up to 100 KB, returns 'x.x KB'
  102400..1048575 : result := format('%.0f KB',[n/1024]);   //up to 1 MB,   returns 'x KB'
  1048576..1073741823 : result := format('%.0f MB',[n/1048576]);   //up to 1 GB,   returns 'x MB'
else
  result := format('%.2f GB',[n/1073741824]);   //1 GB or more, returns 'x.xx GB'
end;
end;

explorer starts showing GB when there is not actually a full GB, the same with MB, just find those bound and change some number in function.
i hope that this will help You ;)
0
 
LVL 8

Expert Comment

by:gmayo
ID: 9805571
Although the computer technical term for a KB, GB etc is 1024x whatever, many use 1000x whatever. This may explain the differences between explorer and the solutions above. Hard drive manufacturers are a prime example of this, claiming their drives have more space than they really do.

Geoff M.
0
 
LVL 17

Assisted Solution

by:geobul
geobul earned 125 total points
ID: 9809401
> i go an incompatible type when dividing it to 1024 many times.

Sure, if you are using an integer variable for the result of dividing while it should be of some real type (float, double, extended, etc.). The result, for instance, would be something like 1.25 MB which is defiantely not integer.

One more thing: you may round file sizes up to blocks of 512 B. Any file written on a diskette occupies one or several blocks of 512 B depending on its size. If a file is 100 B then it will occupy 512 B on a diskette, if the file is 800 B then it will occupy 2x512 B or 1024 B. This can be calculated like:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  Size: Int64;
  res: Int64;
begin
  Size := 0;
  if FileListBox1.SelCount > 0 then begin // there are selected files in the box
    for i := 0 to FileListBox1.Items.Count - 1 do begin // loop the box items
      if FileListBox1.Selected[i] then begin // item i is selected
        res := GetFileSize(FileListBox1.Directory + '\' + FileListBox1.Items[i]); // get the file size
        Size := Size + (((res - 1) div 512) + 1) * 512; // sum in blocks of 512 B - the real diskette size
      end;
    end;
  end;
  ShowMessage(IntToStr(Size)); // show the total size of the selected files
end;

Note: blocks used for hard disks are of different sizes.
 
ZhaawZ gave you examples of displaying the result, so I won't repeat this again.

Regards, Geo
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now