You are here: Home > Articles > Article Display

Calculating the Size of a folder in ASP.NET

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.

Published: Jun 18, 2002
Tested with: ASP.NET 1.1
Category: ASP.NET
23,902 views

Introduction

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


1 <%@Language="VBScript"%>
2 <%Option Explicit%>
3 <%Response.Buffer = True%>
4 <%
5 Dim objFso
6 Dim objFolder
7 Dim lngSize 'size of the folder and its contents
8 Dim folderPath 'virtual or physical path of the folder
9 Set objFso = Server.CreateObject("Scripting.FileSystemObject")
10     objFolder = objFso.GetFolder(folderPath)
11     lngSize = objFolder.Size
12 Set objFso = Nothing
13 Response.Write("Size of folder= " & lngSize)
14 %>

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


1 <%@ Page language="VB" Debug="true" Strict="true" codebehind="default.aspx.vb" src="default.aspx.vb" inherits="DirectorySize" %>
2 <script language="VB" runat="server">
3
4 Sub Page_Load()
5     'get the virtual folder passed in the URL
6     Dim strFolderPath As String = Request.QueryString("Folder")
7     'create instance of our DirectorySize class
8     Dim clsDirectorySize As New DirectorySize
9     'populate the label control
10     lblFolderSize.Text = "Folder Size = " & _
11     clsDirectorySize.Size(strFolderPath)
12 End Sub
13
14 </script>
15 <html>
16 <head>
17     <title>Directory File Size Example</title>
18 </head>
19 <body>
20     <asp:Label id="lblFolderSize" runat="server" />
21 </body>
22 </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

1 Imports System
2 Imports System.IO
3 ...

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

1 ...
2 Public Class DirectorySize
3     Inherits System.Web.UI.Page
4 ...

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.

1 ...
2     Public Function Size(ByVal virtualPath As String) As String
3         'do some basic checking on the folder path passed in the URL
4         If virtualPath = "" Then
5             virtualPath = "/"
6         ElseIf virtualPath.EndsWith("/") Then
7             virtualPath = virtualPath.Substring(0, virtualPath.Length - 1)
8         End If
9         'change folder location from virtual to physical path
10         Dim physicalPath As String = Server.MapPath(virtualPath)
11         'call function GetFolderSize
12         'to get the size of the folder as Double
13         Dim folderSize As Double = GetFolderSize(physicalPath)
14         'call function FormatSize
15         'to format the size as String and for a better display
16         Dim strSize As String = FormatSize(folderSize)
17         'output for this function
18         Return strSize
19     End Function
20 ...

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.

1 ...
2     Private Function GetFolderSize(ByVal physicalPath As String) As Double
3         Dim dblDirSize As Double = 0
4         Dim objDirInfo As DirectoryInfo = New DirectoryInfo(physicalPath)
5         Dim arrChildFiles As Array = objDirInfo.GetFiles()
6         Dim arrSubFolders As Array = objDirInfo.GetDirectories()
7         Dim objChildFile As FileInfo
8         Dim objChildFolder As DirectoryInfo
9         'first loop through the files and add the size of each file
10         For Each objChildFile in arrChildFiles
11             dblDirSize += objChildFile.Length
12         Next
13         'then for each subfolder found call this function again
14         For Each objChildFolder in arrSubFolders
15             dblDirSize += GetFolderSize(objChildFolder.FullName)
16         Next
17         Return dblDirSize
18     End Function
19 ...

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.

1 ...
2     Private Function FormatSize(ByVal dblFileSize as Double) As String
3         If dblFileSize < 1024 Then
4             Return String.Format("{0:N0} B", dblFileSize)
5         ElseIf dblFileSize < 1024 * 1024 Then
6             Return String.Format("{0:N2} KB", dblFileSize/1024)
7         ElseIf dblFileSize < 1024 * 1024 * 1024 Then
8             Return String.Format("{0:N2} MB", dblFileSize/(1024*1024))
9         ElseIf dblFileSize >= 1024 * 1024 * 1024 Then
10             Return "Size in the GB!"
11         End If
12     End Function
13         
14 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.

Conclusion

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.

 



Other articles in this category
  1. Smart headers and footers using ASP.NET User Controls
    December 23, 2002
    Good site usability often means removing links from one page back to itself. In this article we will look at how to create an ASP.NET User Control which will act as a common header to a site. It will automatically know which page we are looking at, and it will remove links to the same page from itself. For example, on this site, if we click on the About us section of the header, it will take you to the page, and it will make that link inactive. That way, we know that we are under that section, and we can't click on it anymore.
  2. Maintaining Sorting while Paging in an ASP.NET Datagrid
    December 18, 2002
    The Datagrid server control offers much control and flexibility in presenting data. Two of the actions that are hard-wired into it are Paging and Sorting. On their own they work great, but not so well together. When you sort a column and then move to a previous or next page, the sorting preference is not maintained. In this article we will see how to maintain both by using the Viewstate object.
  3. How postback works in ASP.NET
    December 10, 2002
    In this article, we will take a closer look at how ASP.NET pages post back to themselves, and how to customize this feature in our web applications.
  4. Viewing and editing file and directory attributes in ASP.NET
    December 2, 2002
    The System.IO.FileAttributes class gives us access to file/directory attributes. In this article, we'll see how to use this class to first read the current attributes and then change them.
  5. Copying a directory in ASP.NET
    November 25, 2002
    The System.IO.DirectoryInfo class does not come with a method to copy a directory. In this article, we'll see how to create a method to do that, and then use it in an ASP.NET page.