Search code examples
vb.netfiledirectoryinfo

Get file size from folder by filter


I'm using vb.net. I wanna ask how I can get the file size for each file by filter? I wanna get all the size of .ts files

here's the code I'm using

Dim TotalSize As Long = 0
Sub FileSize()
    Dim TheSize As Long = GetDirSize(txtPath.Text)

    TotalSize = 0 'Reset the counter

    If TheSize < 1024 Then
        lblSize.Text = Math.Round(TheSize, 0) & " B"
    ElseIf TheSize > 1024 AndAlso TheSize < (1024 ^ 2) Then
        lblSize.Text = Math.Round(TheSize / 1024, 1) & " KB"
    ElseIf TheSize > (1024 ^ 2) AndAlso TheSize < (1024 ^ 3) Then
        lblSize.Text = Math.Round(TheSize / 1024 / 1024, 1) & " MB"
    ElseIf TheSize > (1024 ^ 3) AndAlso TheSize < (1024 ^ 4) Then
        lblSize.Text = Math.Round(TheSize / 1024 / 1024 / 1024, 1) & " GB"
    End If
End Sub
Public Function GetDirSize(folder As String) As Long
    Dim FolderInfo = New DirectoryInfo(folder)
    For Each File In FolderInfo.GetFiles : TotalSize += File.Length
    Next
    For Each SubFolderInfo In FolderInfo.GetDirectories : GetDirSize(SubFolderInfo.FullName)
    Next
    Return TotalSize
End Function

Solution

  • You can use DirectoryInfo.GetFiles() directly, specifying a filter SearchOption.AllDirectories as option, so you'll parse all the sub-folders in the specified path.

    .Net Core 2.1+ also has an EnumerationOptions class and a corresponding overload of GetFiles(). This class allows to collect more parameters related to the search to perform.

    You can simplify a couple of things and use a method that accepts all the parameters needed to perform this action: a Control that will show the result, the Path to parse and the Filter to set ("*.ts" here, as this was the example you posted).

    SetControlTextToFileSize(label1, "C:\SomePath", "*.ts")
    

    Helper and worker methods:

    Private Sub SetControlTextToFileSize(ctrl As Control, folderPath As String, filter As String)
        Dim symbols As String() = {"", "K", "M", "G", "T", "P", "E", "Z", "Y"}
    
        Dim fileSize As ULong = TotalFoldersFileSize(folderPath, filter)
        If fileSize > 0 Then
            Dim lnSizeBase = CInt(Math.Truncate(Math.Log(fileSize, 1024)))
            Dim symbol = symbols(lnSizeBase)
            ctrl.Text = $"{fileSize / Math.Pow(1024, lnSizeBase):N2} {symbol}B"
        Else
            ctrl.Text = "0.00 B"
        End If
    End Sub
    
    Private Function TotalFoldersFileSize(folder As String, pattern As String) As ULong
        Return CULng(New DirectoryInfo(folder).
            GetFiles(pattern, SearchOption.AllDirectories).Sum(Function(f) CULng(f.Length)))
    End Function
    

    The last method in its extended form, in case it's preferable:

    Private Function TotalFoldersFileSize(folder As String, pattern As String) As ULong
        Dim totalSize As ULong
    
        Dim folderInfo = New DirectoryInfo(folder).GetFiles(pattern, SearchOption.AllDirectories)
        For Each fInfo As FileInfo In folderInfo
            totalSize += CULng(fInfo.Length)
        Next
        Return totalSize
    End Function