Solved

FILES SIZE

Posted on 2003-11-22
8
757 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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 

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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

749 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