Solved

FILES SIZE

Posted on 2003-11-22
8
755 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
What is SQL Server and how does it work?

The purpose of this paper is to provide you background on SQL Server. It’s your self-study guide for learning fundamentals. It includes both the history of SQL and its technical basics. Concepts and definitions will form the solid foundation of your future DBA expertise.

 
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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Strange code, can use it, but i cant figure out what it does. 3 60
Delphi 2 60
tidtcpserver connection lost handle 2 84
how can i search if string exist in array ? 3 58
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…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

777 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