Link to home
Start Free TrialLog in
Avatar of elorc
elorcFlag for United States of America

asked on

Calculate a file's size on disk with C#

I'm trying to calculate a file's size on disk (not simply the file size), but it doesn't seem to be working accurately. I initially used a method described on the MSDN forums, which involved using GetDiskFreeSpace to return cluster size. I took the uint value of lpBytesPerSector and performed the following calculation:

uint TotalSize = lpBytesPerSector * ((FileLength + lpBytesPerSector - 1) / lpBytesPerSector)

Open in new window


The result is inaccurate, however. I run this calculation on all of the files in a particular folder, and it returns a value of 3,491,840 bytes. Windows Explorer indicates that the folder's size on disk is 21,057,536 bytes.

Is there a better or more accurate way to perform this calculation?
SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I found the code you were talking about and had zero issues after testing several files of varying lengths. You may have already looked a this, but I would verify that is in fact giving you the total. The large difference makes me wonder if that is the value of a single file.
Avatar of elorc

ASKER

TheLearnedOne: The files are not compressed. With the example that you provided, would that work with network shares as well? In some cases, this program may point to a location like \\someserver\c$ or \\someotherserver\fileshare, so there wouldn't be a drive letter specified. There are a reasonably finite number of targets that the application will be used against, so if necessary I could just have them all mapped as network drives. I'm not really familiar with the WMI that you posted, though, so I don't know if it would work in that case.

Vaulden: Even at an individual file level, it's not returning accurate numbers. This is the code I'm using in one example:

            uint SectorsPerCluster = 0;
            uint ClusterSize = 0;
            uint NumberOfFreeClusters = 0;
            uint TotalNumberOfClusters = 0;

            GetDiskFreeSpace(@"c:\", out SectorsPerCluster, out ClusterSize, out NumberOfFreeClusters, out TotalNumberOfClusters);

            FileInfo f = new FileInfo(@"c:\temp\test.vbs");
            textBox3.Text = string.Format("{0}: Length {1:#,#} bytes, SOD {2:#,#} bytes\r\n", f.ToString(), f.Length, (ClusterSize * ((f.Length + ClusterSize - 1) / ClusterSize)));

Open in new window


The result that I get is:

c:\temp\test.vbs: Length 56 bytes, SOD 512 bytes

According to Windows Explorer, however, test.vbs has a size of 56 bytes and a size on disk of 4,096 bytes.
If you are working with Microsoft Windows servers, then GetCompressedFileSizeW should get you what you need.  The WMI is just a mechanism that I use to access the servers remotely to get BlockSize and NumberOfBlocks for the Win32_Volume.
(new FileInfo(path).Length)


This example gets the size of file stored at my local c:\ drive


using System; 
using System.IO; 
namespace GET.File.Size.Example 
{ 
class Program 
{ 
static void Main() 
{ 
var fi = new FileInfo(@"c:\SQLManagementStudio_x86_ENU.exe"); 
long size = fi.Length; 
Console.WriteLine(size.ToString()); 
Console.ReadLine(); 
} 
} 
} 

Open in new window

Avatar of elorc

ASKER

anuradhay: Right, that gets the size of the file, but it does not return size on disk, which is the value that I'm looking for.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial