Calculate the Size of a Folder/Directory using .NET 4.0

.NET 4.0 introduces 7 New methods to Enumerate Directory and Files in .NET 4.0. All these methods return Enumerable Collections (IEnumerable<T>), which perform better than arrays. We will be using the DirectoryInfo.EnumerateDirectories and DirectoryInfo.EnumerateFiles in this sample which returns an enumerable collection of Directory and File information respectively.

Here’s how to calculate the size of a folder or directory using .NET 4.0 and LINQ. The code also calculates the size of all sub-directories.

C#

using System;
using System.Linq;
using System.IO;

namespace ConsoleApplication3
{
  class Program
  {
    static void Main(string[] args)
    {
      DirectoryInfo dInfo = new DirectoryInfo(@"C:/Articles");
      // set bool parameter to false if you
      // do not want to include subdirectories.
      long sizeOfDir = DirectorySize(dInfo, true);

      Console.WriteLine("Directory size in Bytes : " +
      "{0:N0} Bytes", sizeOfDir);
      Console.WriteLine("Directory size in KB : " +
      "{0:N2} KB", ((double)sizeOfDir) / 1024);
      Console.WriteLine("Directory size in MB : " + 
      "{0:N2} MB", ((double)sizeOfDir) / (1024 * 1024));

      Console.ReadLine();
    }

    static long DirectorySize(DirectoryInfo dInfo, bool includeSubDir)
    {
       // Enumerate all the files
       long totalSize = dInfo.EnumerateFiles()
                    .Sum(file => file.Length);

       // If Subdirectories are to be included
       if (includeSubDir)
       {
          // Enumerate all sub-directories
          totalSize += dInfo.EnumerateDirectories()
                   .Sum(dir => DirectorySize(dir, true));
       }
       return totalSize;
    }
  }
}

VB.NET 10.0 (converted using online tool)

Imports System
Imports System.Linq
Imports System.IO

Module Module1

Sub Main()
   Dim dInfo As New DirectoryInfo("C:/Articles")
   ' set bool parameter to false if you
   ' do not want to include subdirectories.
   Dim sizeOfDir As Long = DirectorySize(dInfo, True)

   Console.WriteLine("Directory size in Bytes : " & _
    "{0:N0} Bytes", sizeOfDir)
   Console.WriteLine("Directory size in KB : " & _
    "{0:N2} KB", (CDbl(sizeOfDir)) / 1024)
   Console.WriteLine("Directory size in MB : " & _
    "{0:N2} MB", (CDbl(sizeOfDir)) / (1024 * 1024))

   Console.ReadLine()
End Sub

Private Function DirectorySize(ByVal dInfo As DirectoryInfo, _
   ByVal includeSubDir As Boolean) As Long
   ' Enumerate all the files
   Dim totalSize As Long = dInfo.EnumerateFiles() _
     .Sum(Function(file) file.Length)

   ' If Subdirectories are to be included
   If includeSubDir Then
     ' Enumerate all sub-directories
     totalSize += dInfo.EnumerateDirectories() _
      .Sum(Function(dir) DirectorySize(dir, True))
   End If
   Return totalSize
End Function

End Module


OUTPUT

I got the following output after running this code.

image

To confirm that the code worked as expected, I opened Windows Explorer > C Drive > Right clicked the folder > Properties. Here is the screenshot that matches the output we got from our code

image




About The Author

Suprotim Agarwal
Suprotim Agarwal, Developer Technologies MVP (Microsoft Most Valuable Professional) is the founder and contributor for DevCurry, DotNetCurry and SQLServerCurry. He is the Chief Editor of a Developer Magazine called DNC Magazine. He has also authored two Books - 51 Recipes using jQuery with ASP.NET Controls. and The Absolutely Awesome jQuery CookBook.

Follow him on twitter @suprotimagarwal.

8 comments:

Anonymous said...

The VB example, while technically correct, is not how it is usually done.

Imports System.Console
Imports System.IO

Module Module1

Sub Main()
Dim dInfo As New DirectoryInfo("C:/Temp")
' set bool parameter to false if you
' do not want to include subdirectories.
Dim sizeOfDir = DirectorySize(dInfo)

WriteLine("Directory size in Bytes : {0:N0} Bytes", sizeOfDir)
WriteLine("Directory size in KB : {0:N2} KB", sizeOfDir / 1024)
WriteLine("Directory size in MB : {0:N2} MB", sizeOfDir / (1024 * 1024))

ReadLine()
End Sub

Private Function DirectorySize(ByVal dInfo As DirectoryInfo, Optional ByVal includeSubDir As Boolean = True) As Long
' Enumerate all the files
Dim totalSize = Aggregate file In dInfo.EnumerateFiles() Into Sum(file.Length)

' If Subdirectories are to be included
If includeSubDir Then
' Enumerate all sub-directories
totalSize += Aggregate dir In dInfo.EnumerateDirectories Into Sum(DirectorySize(dir))
End If

Return totalSize
End Function

End Module

1. You never have to import System or LINQ
2. Import System.Console to avoid writing `Console.` everwhere
3. VB has LINQ syntax for aggragates.
4. Type inference is a good thing.
5. Optionals are also a good thing when used responsibly.
6. The `/` operator already returns doubles. For intereger division use `\`.
7. Underscores are only needed in LINQ expressions, the rest of the time it is implied by the context.

Suprotim Agarwal said...

Anonymous: Thanks so much for the correct VB snippet.

Gurpreet Gill said...

GR8 code. this help me a-lot & this is more & more faster than this
http://msdn.microsoft.com/en-us/library/bb546167.aspx

Thanks
Gurpreet Gill

Anonymous said...

What about system volumes? What about directories you don't have permission over? This is an incomplete example.

Unknown said...

Hi,

After calculating the file size if it exceeds it limit(for eg-200mb)in that case i want to send an email to the user.how it can be possible .Any help

Unknown said...

Good!

Unknown said...

Hi,

Thank you, program did work for me but how would I change it if I want both total size of the folder (What I get using the above C# program) and then similarly I want size of each subfolder. I would really appreciate you help as I am a newbie.

Thanks

Suprotim Agarwal said...

The code includes subdirectories.

// If Subdirectories are to be included
if (includeSubDir)
{
// Enumerate all sub-directories
totalSize += dInfo.EnumerateDirectories()
.Sum(dir => DirectorySize(dir, true));
}