FILES SIZE

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..
aerokevsAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jcondeCommented:
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
geobulCommented:
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
geobulCommented:
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
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

ZhaawZSoftware DeveloperCommented:
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
aerokevsAuthor Commented:
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
ZhaawZSoftware DeveloperCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gmayoCommented:
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
geobulCommented:
> 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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.