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:
- System.IO.Directory
- 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.
Very interesting article !