IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Parcours rapide d'un ensemble de répertoires/fichiers à 4 niveaux - possibilité d'accélérer ?


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2014
    Messages : 33
    Par défaut Parcours rapide d'un ensemble de répertoires/fichiers à 4 niveaux - possibilité d'accélérer ?
    Bonjour à Tou(te)s,

    En premier, excusez moi si ce sujet a déjà été posé, j'ai fait plusieurs recherches mais n'ai pas trouvé ce que je recherche... donc dites le moi si je "doublonne".

    Le problème est de déterminer le nombre de fichiers et la somme de leurs tailles sous un répertoire, lequel étant au deuxième ou troisième niveau d'une structure.
    et de rentrer chaque répertoire avec ces informations dans un tableau.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        R1 -|
            R2 - |
                 R3 - | - F1... Fn                            >  R1\R2\F1...Fn       ce qui donne dans le tableau     R1\R2\20F/256260B
                      F1... Fn                                >  R1\R2\R3\F1...Fn                                     R1\R2\R3\20F/256260B
    Simple... n'est-ce pas ?
    Sauf que pour 33100 répertoires (et quelques 1 900 000 fichiers) mon programme prend plus de 35mn... alors qu'un logiciel XYExplorer parcourt les mêmes en 32s

    Bon, le mien fait des sommes pour calculer les tailles des répertoires, range tout cela dans un tableau, etc... mais tout de même la différence est énorme.

    Ma question est donc... comment puis-je modifier mon programme de façon à ce qu'il prenne moins de 35mn ?
    (d'autant plus que le nombre de répertoires et de fichiers va continuer à augmenter)

    Merci d'avance.

    PS: dans mon programme j'utilise "Computer.FileSystem.GetDirectories" et "Computer.FileSystem.GetFiles" imbriqués...
    ce qui doit être moins "puissant" que des appels aux API Windows... mais plus "standard" parait-il...

  2. #2
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2013
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 563
    Par défaut
    Citation Envoyé par Delthi59 Voir le message
    Ma question est donc... comment puis-je modifier mon programme de façon à ce qu'il prenne moins de 35mn ?
    (d'autant plus que le nombre de répertoires et de fichiers va continuer à augmenter)
    Aurais-tu l'algo de ton programme? Ca serait pratique pour essayer de t'aider

  3. #3
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2005
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2005
    Messages : 562
    Par défaut
    Bonjour,

    En effet il nous faudra l'algo .
    Mais as-tu déjà essayé de voir qu'elles sont les étapes les plus gourmandes ?
    Si tu fais un GetFile sur une telle structure ça ne m'étonnerais pas qu'a lui seul il prenne 1 tiers voir la moitié du temps d'exécution, il n'est pas vraiment performant. Maintenant il faut tester pour être sur que c'est le principale consommateur.
    D'ailleurs une recherche rapide m'a donné un GetFiles Faster

    J@ck.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    computer.filesystem doit renvoyer vers system.io, qui lui doit appeler les api ...

    sinon tu peux multithreader le tout pour voir si c'est mieux
    genre au début tu cherches les dossiers à ta racine (ca doit aller très vite) et la taille de ceux ci
    ensuite tu utilises le thread pool pour demander le contenu de chacun de ces dossiers

    le mieux serait aussi de dissocier les dossiers et leur taille
    d'ailleurs les dossiers ca doit être très rapide, auquel cas seul la taille serait à déporter en multithreading
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre très actif Avatar de joKED
    Profil pro
    Imposteur en chef
    Inscrit en
    Février 2006
    Messages
    339
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Imposteur en chef

    Informations forums :
    Inscription : Février 2006
    Messages : 339
    Par défaut
    Sans l'avoir testé pour autant, as tu essayé d'utiliser les fonctions EnumerateFiles et EnumerateDirectories au lieu de GetFiles et GetDirectories ?

    Dépendant de ce que tu en fait, ça pourrait bien être plus rapide.

    D'après la doc :

    The EnumerateFiles and GetFiles methods differ as follows: When you use EnumerateFiles, you can start enumerating the collection of names before the whole collection is returned; when you use GetFiles, you must wait for the whole array of names to be returned before you can access the array. Therefore, when you are working with many files and directories, EnumerateFiles can be more efficient.

  6. #6
    Membre actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2014
    Messages : 33
    Par défaut
    Waou.... merci pour toutes ces réponses

    Pour ceux qui me l'ont demandé et pour (peut-être) faire avancer un peu plus le "schmilblick"... voici un extrait de mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
     
    sDir   contient le répertoire racine de ma structure
    <...> divers traitements (pas trop lourds: création de chaine gardant diverses infos dont taille et nb fichiers de chaque répertoire, 
            rangement de la chaine en tableaux pour tri, etc...)
     
                Try            
                    For Each di1 As String In My.Computer.FileSystem.GetDirectories(sDir, FileIO.SearchOption.SearchTopLevelOnly)           ' Niveau 1 (0-9...Z)
                        TaiD1 = 0 : NbED1 = 0
     
                        For Each di2 As String In My.Computer.FileSystem.GetDirectories(di1, FileIO.SearchOption.SearchTopLevelOnly)        ' Niveau 2 (1_\...)
                            TaiD2 = 0 : NbED2 = 0
     
                            For Each di3 As String In My.Computer.FileSystem.GetDirectories(di2, FileIO.SearchOption.SearchTopLevelOnly)    ' Niveau 3 (2_\...)
                                TaiD3 = 0 : NbED3 = 0
                                Dim dF3 As Decimal = 0
                                For Each infoF3 In My.Computer.FileSystem.GetDirectoryInfo(di3).GetFiles                              ' Niveau 3'(3_\files)
                                  dF3 += (infoF3.Length / 1024)
                                  NbED3 += 1
                                Next
                                TaiD3 += Decimal.Round(dF3, 0, MidpointRounding.AwayFromZero)
     
                                    <....>
     
                                TaiD2 += TaiD3
                                NbED2 += NbED3
                            Next
     
                            For Each fi2 As String In My.Computer.FileSystem.GetFiles(di2, FileIO.SearchOption.SearchTopLevelOnly, "*.pdf", "*.avi")    ' Niveau 3 (2_\...)
                                TaiF2 = Decimal.Round((My.Computer.FileSystem.GetFileInfo(fi2).Length / 1024), 0, MidpointRounding.AwayFromZero)
                                TaiD2 += TaiF2
                                NbED2 += 1
                            Next
     
                            Dim dF2 As Decimal = 0
                            For Each fi2 As String In My.Computer.FileSystem.GetFiles(di2, FileIO.SearchOption.SearchTopLevelOnly, "*.bmp", "*.jp*", "*.png", "*.*if")    ' Niveau 3
                                 dF2 += (My.Computer.FileSystem.GetFileInfo(fi2).Length / 1024)
                                 NbED2 += 1
                            Next
                            TaiD2 += Decimal.Round(dF2, 0, MidpointRounding.AwayFromZero)
     
                                    <....>
     
                            TaiD1 += TaiD2
                            NbED1 += NbED2
                        Next
                    Next
     
                Catch ex As Exception
                    MsgBox("Pb CreateFile:" + vbCrLf + ex.Message)
                End Try
    Alors évidemment ce n'est sans doute pas l'idéal de code (je l'avais créé il y a au moins 3 ans) mais je cherche surtout à optimiser les parcours de répertoires/fichiers.

    @Pol63... Je ne sais pas...
    Comment peut-on, sous Windows, obtenir la taille d'un répertoire sans faire la somme des répertoires sous lui et donc celles des fichiers sous ceux-ci ?
    Je n'ai pas trouvé de fonction permettant cela (contrairement aux autres systèmes par exemple UNIX).
    A noter que pour "accélérer" le programme j'ai placé des fichiers ".sze" qui reprennent "taille" et "nb fichiers" sous chaque répertoire et je ne recalcule ces fichier
    que lorsqu'il y a une différence dans les dates de modification... ce qui m'oblige cependant à parcourir toute la structure des répertoires (hors fichiers) pour obtenir
    les dates de modification...

    Merci de vos propositions , je vais de ce pas consulter le lien "GetFiles Faster" et voir si Enumeratexxx peut convenir dans mon cas.
    A+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 03/03/2016, 19h48
  2. Réponses: 1
    Dernier message: 08/04/2015, 22h47
  3. Réponses: 5
    Dernier message: 27/05/2007, 23h20
  4. Problème pour liste répertoires/fichiers
    Par pymouse dans le forum C
    Réponses: 1
    Dernier message: 15/12/2006, 11h45
  5. Matrice : creation et parcours rapide
    Par CaptainChoc dans le forum Calcul scientifique
    Réponses: 6
    Dernier message: 10/05/2006, 15h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo