Solved

FILES SIZE

Posted on 2003-11-22
8
753 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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

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…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

757 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

20 Experts available now in Live!

Get 1:1 Help Now