Blog Home  Home Feed your aggregator (RSS 2.0)  
Eric Malamisura's Blog - C# Getting "Actual Size" of File
Geek Ramblings
 
 Thursday, April 13, 2006

While writing a utility that I will soon release, in the near future I found that unusually .NET doesnt support a method to get the "Actual Size" of a file on the disk.  To know what I am talking about, right click a file in Windows Explorer and look at its properites.  You will notice there are two sizes listed, the file size and the actual file size.  The difference being that based on your file system, a small file can be larger and a large file can be smaller which is all deteremined by cluster size differences.  Normally this isnt a huge issue, but if you want to know how much space something is using up on your disk, you will want to know exactly how much space its using, otherwise you may get a distorted outlook on space usage.

With that said, I have written a method that can be used in .NET that will offer the information needed to write this functionality.  To get the "Actual Size" you need to know the ClusterSize. Since I couldnt find anything from searching the net I thought I would offer this in case someone wanted to do the same thing, I wrote this so it will give you the same object oriented feel that .NET gives you so it shouldnt feel unusual to use.


[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool GetDiskFreeSpace([MarshalAs(UnmanagedType.LPTStr)]string rootPathName,
ref int sectorsPerCluster, ref int bytesPerSector, ref int numberOfFreeClusters, ref int totalNumbeOfClusters);

public static DiskInfo GetDiskDiskInfo(string rootPathName)
{
DiskInfo diskInfo = new DiskInfo();
int sectorsPerCluster = 0, bytesPerSector = 0, numberOfFreeClusters = 0, totalNumberOfClusters = 0;
GetDiskFreeSpace(rootPathName, ref sectorsPerCluster, ref bytesPerSector, ref numberOfFreeClusters, ref totalNumberOfClusters);

diskInfo.RootPathName = rootPathName;
diskInfo.SectorsPerCluster = sectorsPerCluster;
diskInfo.BytesPerSector = bytesPerSector;
diskInfo.NumberOfFreeClusters = numberOfFreeClusters;
diskInfo.TotalNumberOfClusters = totalNumberOfClusters;

return diskInfo;
}

public struct DiskInfo
{
public string RootPathName;
public int SectorsPerCluster;
public int BytesPerSector;
public int NumberOfFreeClusters;
public int TotalNumberOfClusters;
}

//Forgot to add this on my initial post, and I just noticed.
public static int GetActualFileSize(FileInfo file)
{
double clusterSize = 0;
double numberofClusters = 0;
int actualSize = 0;
DiskInfo diskInfo = new DiskInfo();
diskInfo = GetDiskInfo(file.Directory.Root.FullName);

clusterSize = (diskInfo.BytesPerSector * diskInfo.SectorsPerCluster);

//Added this, seems if the file length and clustersize are exact it would over-report the size
if
((file.Length % clusterSize) > 0)
clusterSize += 1;

numberofClusters = Math.Round(file.Length / clusterSize);

actualSize = (int)(numberofClusters * clusterSize);
return actualSize;
}


Thursday, April 13, 2006 4:29:09 PM (GMT Standard Time, UTC+00:00)  #    Comments [1]    | 
Friday, August 03, 2007 3:07:53 PM (GMT Standard Time, UTC+00:00)
Thanks for that, Eric.
There's a small typo: "GetDiskDiskInfo" (4th line) should be "GetDiskInfo"
Ulli
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):

Copyright © 2009 Eric Malamisura. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.