What’s the best way to calculate the size of a directory in VB .NET?

Doing the work in parallel should make it faster, at least on multi-core machines. Try this C# code. You will have to translate for VB.NET.

private static long DirSize(string sourceDir, bool recurse) 
{ 
    long size = 0; 
    string[] fileEntries = Directory.GetFiles(sourceDir); 

    foreach (string fileName in fileEntries) 
    { 
        Interlocked.Add(ref size, (new FileInfo(fileName)).Length); 
    } 

    if (recurse) 
    { 
        string[] subdirEntries = Directory.GetDirectories(sourceDir); 

        Parallel.For<long>(0, subdirEntries.Length, () => 0, (i, loop, subtotal) => 
        { 
            if ((File.GetAttributes(subdirEntries[i]) & FileAttributes.ReparsePoint) != FileAttributes.ReparsePoint) 
            { 
                subtotal += DirSize(subdirEntries[i], true); 
                return subtotal; 
            } 
            return 0; 
        }, 
            (x) => Interlocked.Add(ref size, x) 
        ); 
    } 
    return size; 
} 

Though this answer is talking about Python, the concept applies here as well.

Windows Explorer uses system API calls FindFirstFile and FindNextFile recursively to pull file information, and then can access the file sizes very quickly through the data that's passed back via a struct, WIN32_FIND_DATA: http://msdn.microsoft.com/en-us/library/aa365740(v=VS.85).aspx.

My suggestion would be to implement these API calls using P/Invoke, and I believe you will experience significant performance gains.


This is a short and sweet code snippet that will get the job done. You just need to reset the counter before you call the function

Public Class Form1
Dim TotalSize As Long = 0
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    TotalSize = 0 'Reset the counter
    Dim TheSize As Long = GetDirSize("C:\Test")
    MsgBox(FormatNumber(TheSize, 0) & " Bytes" & vbCr & _
           FormatNumber(TheSize / 1024, 1) & " Kilobytes" & vbCr & _
           FormatNumber(TheSize / 1024 / 1024, 1) & " Megabytes" & vbCr & _
           FormatNumber(TheSize / 1024 / 1024 / 1024, 1) & " Gigabytes")
End Sub
Public Function GetDirSize(RootFolder As String) As Long
    Dim FolderInfo = New IO.DirectoryInfo(RootFolder)
    For Each File In FolderInfo.GetFiles : TotalSize += File.Length
    Next
    For Each SubFolderInfo In FolderInfo.GetDirectories : GetDirSize(SubFolderInfo.FullName)
    Next
    Return TotalSize
End Function
End Class