7
votes

Quelle est la meilleure façon de calculer la taille d'un répertoire dans VB .NET?

Je dois calculer la taille du répertoire dans VB .NET

Je connais les 2 méthodes suivantes P>

Méthode 1: de MSDN http://msdn.microsoft.com/en-us/library/system.io.directory.aspx p>

'L'exemple suivant calcule la taille d'un répertoire 'et ses sous-répertoires, le cas échéant, et affiche la taille totale 'En octets. p> xxx pré>

méthode 2: de Quelle est la meilleure façon de calculer la taille d'un répertoire dans .NET? P>

Dim size As Int64 = (From strFile In My.Computer.FileSystem.GetFiles(strFolder, _
              FileIO.SearchOption.SearchAllSubDirectories) _
              Select New System.IO.FileInfo(strFile).Length).Sum()


0 commentaires

7 Réponses :


4
votes

Bien que cette réponse parle de Python , le concept s'applique également ici.

Explorer Windows utilise des appels d'API système FindFirstFile et FINTNEXTFILE RÉSUCIULLÉ pour extraire des informations de fichier, puis peut accéder aux tailles de fichiers très rapidement via les données qui sont transmises via un < code> struct , win32_find_data : http://msdn.microsoft.com/en-us/library/aa365740 (v = vs.85) .aspx .

Ma suggestion serait de mettre en œuvre ces appels d'API à l'aide de P / invoke, et je pense que vous rencontrerez des gains de performance significatifs.


0 commentaires

5
votes

Faire le travail en parallèle devrait le rendre plus rapide, du moins sur des machines multi-noyau. Essayez ce code C #. Vous devrez traduire pour 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; 
} 


0 commentaires

3
votes

Ceci est un extrait de code court et sucré qui obtiendra le travail. Il vous suffit de réinitialiser le compteur avant d'appeler la fonction

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


2 commentaires

@ Magicprog.fr, belle boucle. Pouvez-vous me dire quel est le truc avec réinitialiser le compteur ici? Pourquoi retourne-t-il toujours la taille du dossier avec tous les sous-dossiers? Je ne comprends tout simplement pas ...


@ Luckyluke82 L'opérateur ":" vous permet de prétendre qu'il y a une autre ligne sans appuyer sur Entrée, il ajoute donc la taille de chaque fichier, puis ajoute de manière récursive les fichiers de chaque sous-répertoire ... Bien qu'ils ont oublié d'ajouter la taille du sous-répertoire. -Directoires à la taille totale :)



0
votes

Code VB basé sur la réponse de Jamie:

Imports System.Threading
Imports System.IO

Public Function GetDirectorySize(ByVal path As String, Optional recurse As Boolean = False) As Long
    Dim totalSize As Long = 0
    Dim files() As String = Directory.GetFiles(path)
    Parallel.For(0, files.Length,
                   Sub(index As Integer)
                     Dim fi As New FileInfo(files(index))
                     Dim size As Long = fi.Length
                     Interlocked.Add(totalSize, size)
                   End Sub)

    If recurse Then
        Dim subDirs() As String = Directory.GetDirectories(path)
        Dim subTotal As Long = 0
        Parallel.For(0, subDirs.Length,
                       Function(index As Integer)
                         If (File.GetAttributes(subDirs(index)) And FileAttributes.ReparsePoint) <> FileAttributes.ReparsePoint Then
                           Interlocked.Add(subTotal, GetDirectorySize(subDirs(index), True))
                           Return subTotal
                         End If
                         Return 0
                       End Function)
      Interlocked.Add(totalSize, subTotal)
    End If

    Return totalSize
End Function


2 commentaires

Ne compile pas. Interlocké UNDÉFINÉ.


@stigzler Il est défini dans System.threading. Vérifiez la réponse mise à jour.



0
votes

ici aussi court que je peux l'obtenir.

Il affichera la taille de la boîte sélectionnée dans une boîte de message. Vous allez avoir besoin d'un folderbrowserdialog dans le formulaire pour que cela fonctionne. xxx


0 commentaires

0
votes

Essayez ceci pour obtenir la taille totale dans GB

    Dim fso = CreateObject("Scripting.FileSystemObject")
    Dim profile = fso.GetFolder("folder_path")
    MsgBox(profile.Size / 1073741824)


0 commentaires

1
votes

gros merci@jamie pour le code et @mathiasfk pour la traduction de vb.net. Je l'utilise pour mon propre programme de sauvegarde qui, dans le paramètre par défaut, il suffit de sauvegarder l'ensemble du dossier de profil, c'est un code qui est également capable de comprendre les points de jonction et de lire une taille plus ou moins correcte. C'est au moins d'accord pour la sauvegarde. : -)

J'ai juste dû mettre du code au sein d'essayer de sorte qu'il ne s'arrête pas pour les dossiers qu'il n'a pas accès à, si vous pouviez également avoir un tel problème, utilisez-le simplement (ne gère pas l'erreur simplement. , vous pouvez ajouter si important pour vous): xxx


0 commentaires