In classic ASP it’s very easy to get the size of a folder since the FileSystemObject (FSO) class includes a Size function. In ASP.NET there is no such function provided, so we’ll see how to create one, extending the System.IO.DirectoryInfo Namespace.

Doing it with classic ASP

<%@Language="VBScript"%>
<%Option Explicit%>
<%Response.Buffer = True%>
<%
Dim objFso
Dim objFolder
Dim lngSize 'size of the folder and its contents
Dim folderPath 'virtual or physical path of the folder
Set objFso = Server.CreateObject("Scripting.FileSystemObject")
	objFolder = objFso.GetFolder(folderPath)
	lngSize = objFolder.Size
Set objFso = Nothing
Response.Write("Size of folder= " & lngSize)
%>

The script above, written in VBScript, shows how simple this is. We populate the folderPath variable through some way (like passing it through the QueryString or a Post), and then simply use the FileSystemObject (FSO) to read the Size.

Working with Directories in ASP.NET

.NET provides two Namespaces to work with Directories:

  1. System.IO.Directory
  2. System.IO.DirectoryInfo

The following Properties are offered by default:

Property Name Accessibility
Attributes (Get , Set)
CreationTime (Get , Set)
Exists (Get)
Extension (Get)
FullName (Get)
LastAccessTime (Get , Set)
LastWriteTime (Get , Set)
Name (Get)
Parent (Get)
Root (Get)

Clearly, there is no Size or Length Property, unlike the equivalent namespace for files, which does have a Length Property.

We will be creating 2 pages which will complete our application. One is the HTML page, which has the Label Control to output the folder size, which the second is the code behind, which keeps all the necessary code to make things work. Let’s see the HTML page first.

default.aspx

<%@ Page language="VB" Debug="true" Strict="true" codebehind="default.aspx.vb" src="default.aspx.vb" inherits="DirectorySize" %>
<script language="VB" runat="server">

Sub Page_Load()
	'get the virtual folder passed in the URL
	Dim strFolderPath As String = Request.QueryString("Folder")
	'create instance of our DirectorySize class
	Dim clsDirectorySize As New DirectorySize
	'populate the label control
	lblFolderSize.Text = "Folder Size = " & _
	clsDirectorySize.Size(strFolderPath)
End Sub

</script>
<html>
<head>
	<title>Directory File Size Example</title>
</head>
<body>
	<asp:Label id="lblFolderSize" runat="server" />
</body>
</html>

Name this file default.aspx. The first line tells our page to inherit from a class called DirectorySize, which resides in default.aspx.vb.  I have both a codebehind and a src defined, pointing to the same file, since Visual Studio .NET (VS.NET) wants that codebehind command to find the code, while a simple ASP.NET page wants the src.  Using both will still work fine and you can work in VS.NET and your favorite text editor (like Notepad).

The folder to get the size needs to be passed to this page through the URL. I will also assume that the folder is a virtual one. You can of course, change this to fit your needs. For example, to return the value of the size of a folder called images which resides in the root folder of your site, type this in the URL:
http://localhost/default.aspx?Folder=/images

So, first we get the folder to query, then we create an instance of our class, and set the Label control’s lablFolderSize.Text property equal to the Size function of the class.

default.aspx.vb

Imports System
Imports System.IO
...

These 2 Namespaces are the minimum we need to get our class to work.

...
Public Class DirectorySize
	Inherits System.Web.UI.Page
...

We define our class giving it a name of our choice, and then inherit the basic Page controls from the Namespace. This is necessary in order for this code to be pluggable into the default.aspx page.

...
	Public Function Size(ByVal virtualPath As String) As String
		'do some basic checking on the folder path passed in the URL
		If virtualPath = "" Then
			virtualPath = "/"
		ElseIf virtualPath.EndsWith("/") Then
			virtualPath = virtualPath.Substring(0, virtualPath.Length - 1)
		End If
		'change folder location from virtual to physical path
		Dim physicalPath As String = Server.MapPath(virtualPath)
		'call function GetFolderSize
		'to get the size of the folder as Double
		Dim folderSize As Double = GetFolderSize(physicalPath)
		'call function FormatSize
		'to format the size as String and for a better display
		Dim strSize As String = FormatSize(folderSize)
		'output for this function
		Return strSize
	End Function
...

The function Size is the one called from the default.aspx file. It accepts the folder path as a virtual one, and after some basic checking, changes it to a physical path with the Server.MapPath method.

Then we pass the folder path to another function, GetFolderSize, which returns the size of the folder as type Double, and before we return the value, we sent it along to another function, called FormatSize, which returns the value as a String in a more nicely formatted way.

...
	Private Function GetFolderSize(ByVal physicalPath As String) As Double
		Dim dblDirSize As Double = 0
		Dim objDirInfo As DirectoryInfo = New DirectoryInfo(physicalPath)
		Dim arrChildFiles As Array = objDirInfo.GetFiles()
		Dim arrSubFolders As Array = objDirInfo.GetDirectories()
		Dim objChildFile As FileInfo
		Dim objChildFolder As DirectoryInfo
		'first loop through the files and add the size of each file
		For Each objChildFile in arrChildFiles
			dblDirSize += objChildFile.Length
		Next
		'then for each subfolder found call this function again
		For Each objChildFolder in arrSubFolders
			dblDirSize += GetFolderSize(objChildFolder.FullName)
		Next
		Return dblDirSize
	End Function
...

We store the files and subfolders into 2 local arrays. We can use the Length property of each file found to add to the total size of the parent folder, and for each subfolder found we run the function again.  This will run recursively until there are no more files or subfolders left. If your folders are very deep and big, then make sure to check your server timeout value, as this may take a while to run.

...
	Private Function FormatSize(ByVal dblFileSize as Double) As String
		If dblFileSize < 1024 Then
			Return String.Format("{0:N0} B", dblFileSize)
		ElseIf dblFileSize < 1024 * 1024 Then
			Return String.Format("{0:N2} KB", dblFileSize/1024)
		ElseIf dblFileSize < 1024 * 1024 * 1024 Then
			Return String.Format("{0:N2} MB", dblFileSize/(1024*1024))
		ElseIf dblFileSize >= 1024 * 1024 * 1024 Then
			Return "Size in the GB!"
		End If
	End Function

End Class

I am simply converting the byte count to a String, and adding the B, KB, MB and GB extension appropriately.  Since the GetFolderSize function in this case can not be bigger than GBs worth of bytes, I output an error message instead.

You can take these 3 functions out of a class if you prefer, and instead simply add them to the Sub Page_Load method of the default.aspx page. That way there is no need for any codebehind pages. I prefer this way though, as we separate VB code from presentation HTML. Ultimately, it’s up to you.

One Response to Calculating the Size of a folder in ASP.NET

  • francesco

    Very interesting article !