begin process at 2008 07 04 00:56:01
1 204 456 membres
3 nouveaux aujourd'hui
14 114 membres club

Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum.
Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

LISTEZ VOS FICHIER FACILEMENT ET RAPIDEMENT


Information sur la source

Catégorie :API Classé sous : dir, lister, enumerer, fichier, rapide Niveau : Débutant Date de création : 02/08/2007 Date de mise à jour : 19/11/2007 03:01:02 Vu / téléchargé: 6 122 / 695

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (10)
Ajouter un commentaire et/ou une note


Description

Je pars du même constat que Jack a fait concernant sa source "REMPLACER DIR PAR UNE CLASSE DIR2 (AVANTAGES) "
http://www.vbfrance.com/code.aspx?ID=37859

Ce constat est le suivant:
  Dir est rapide est simple à mettre en place pour énumérer une liste de fichiers / dossiers.
  néanmoins, il ne peut être utiliser en récursion. Pas possible, donc, de lister facilement une arborescence.

  FSO permet lui de lister toute une arborescence, mais est à proscrire dans vos programme, laissez le dans les Scripts, il a été
  conçu pour ça. Et pour cause ! il est extrêmement lent...

Il s'agit d'une simple classe, qui permet de lister facilement et rapidement vos Fichier/Dossiers, comme le fais Dir
J'ai donc grandement remanié le code de Jack, que je vous poste maintenant.

Outre la manière de se servir de ma classe qui diffère de celle de Jack, j'ai ajouté la possibilité d'accéder aux dates et a la taille du fichier

Source

  • '# Son utilisation est fort simple :
  • Dim oItems As CDir
  • Set oItems = New CDir
  • oItems.Initialize "C:\MonDossier\" '# Par défault, fichiers et dossiers vont être listés
  • '# On boucle, tant qu'on n'est pas a la fin de la liste.
  • Do Until oItems.EOF
  • '# Si l'element en cours est un dossier ...
  • If CBool(oItems.Attributes And vbDirectory) Then
  • '# Pour l'exemple, on créé un noeud avec le dossier. la clé est le chemin complet vers
  • '# le dossier. le texte du noeud est son nom
  • Set oNode = CcTree.Nodes.Add(voParent, tvwChild, oItems.FullPath, oItems.Name)
  • FillList oItems.FullPath & "\", oNode
  • Else
  • '# Ici, pour l'exemple, on ajoute le fichier dans une liste.
  • '# On peut acceder a la date de creation/modification/accès du fichier
  • '# (plus rapide que de faire un appel séparé à FileLen ou FileDateTime)
  • AddFile oItems.FullPath, oItems.FileSize, oItems.LastWriteDate
  • End If
  • '# On passe a l'element suivant
  • oItems.MoveNext
  • Loop
'# Son utilisation est fort simple :
Dim oItems As CDir
    Set oItems = New CDir
    oItems.Initialize "C:\MonDossier\"  '# Par défault, fichiers et dossiers vont être listés
    '# On boucle, tant qu'on n'est pas a la fin de la liste.
    Do Until oItems.EOF
        '# Si l'element en cours est un dossier ...
        If CBool(oItems.Attributes And vbDirectory) Then
            '# Pour l'exemple, on créé un noeud avec le dossier. la clé est le chemin complet vers
            '# le dossier. le texte du noeud est son nom
            Set oNode = CcTree.Nodes.Add(voParent, tvwChild, oItems.FullPath, oItems.Name)
            FillList oItems.FullPath & "\", oNode
        Else
            '# Ici, pour l'exemple, on ajoute le fichier dans une liste.
            '# On peut acceder a la date de creation/modification/accès du fichier
            '# (plus rapide que de faire un appel séparé à FileLen ou FileDateTime)
            AddFile oItems.FullPath, oItems.FileSize, oItems.LastWriteDate
        End If

        '# On passe a l'element suivant
        oItems.MoveNext
    Loop
Pour les "Membres Club", vous pouvez télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip

02 août 2007 14:08:45 :
Ajout d'une Form de test
03 août 2007 15:07:11 :
Utilisation de l'API Unicode
19 novembre 2007 03:01:03 :
Suppression d'un Doevents et léger remaniement de la propriété Name => un peu plus rapide
  • signaler à un administrateur
    Commentaire de asimengo le 02/08/2007 18:59:36

    Bonjour Renf, Je reprends ton brillant travail dans la logique dont je parlais (voir commentaire sur source de Jack). Initialize et MoveNext entraine le positionnement de mtFileInfo directement sur le nom (fichier ou dossier) valide. Il s'agit juste d'une différence algorithmique mais le fond est totalement le même et vient de toi.
    Avec l'exemple de ta source je n'arrive pas à déterminer lequel est plus rapide, les temps sont variables. Mais le plus important pour moi c'est d'avoir ton analyse de mon algorithme et expliquer les différences avec le tien, quand aux temps d'exécution, parce que je ne suis pas encore expert dans cette optimisation.
    NB: Je ne me suis pas penché sur les commentaires.
    ------------------------------------------------------------------------------------------------

    Option Explicit

    Private mhFind As Long
    Private meRequiredAttributes As Long
    Private mtFileInfo As WIN32_FIND_DATA
    Private msName As String
    Private msPath As String

    '# On démarre une nouvelle enumeration
    '# Par default, on accepte tousles atributs
    Public Sub Initialize(ByVal vsPath As String, Optional veAttributes As FileAttributes = &HFFFFFFFF)
    Dim i As Long
        
        '# Si une recherche etait deja en cours, on la stoppe
        If mhFind > 0 Then Call FindClose(mhFind)
        
        '# On récupère le chemin
        i = InStrRev(vsPath, "\")
        If i Then
            msPath = Left$(vsPath, i)
        Else
            msPath = vbNullString
        End If
        
        '# Si nous avons 'C:\MonDossier\'
        '# Rien ne sera trouvé... on ajoute donc un joker
        If i = Len(vsPath) Then vsPath = vsPath & "*"

        '# On démarre la recherche
        mhFind = FindFirstFile(vsPath, mtFileInfo)
        If mhFind > 0 Then
            '# La requete a été acceptée. On enregistre les parametres de la recherche
            meRequiredAttributes = veAttributes
            '# Permet de passer sur un fichier valide.
            If Not ItemEnCoursValide Then Call RechercheProchainItemValide
        End If

    End Sub

    ''# Permet de savoir s'il existe une session cDir.
    'Public Property Get State() As Long
    '    State = IIf(mhFind > 0, 1, 0)
    'End Property

    '# Renvoie le repertoire courant de la recherche
    Public Property Get Path() As String
        Path = msPath
    End Property

    '# Renvoie le chemin complet de l'element listé en cours
    Public Property Get FullPath() As String
        If mhFind > 0 Then FullPath = msPath & msName
    End Property

    '# Renvoie le nom (du fichier ou dossier) en cours valide.
    Public Property Get Name() As String
        Name = msName
    End Property

    Private Function ItemEnCoursValide() As Boolean
    Dim nLength As Long
        
        nLength = InStr(mtFileInfo.cFileName, vbNullChar)
        If nLength Then
            msName = Left$(mtFileInfo.cFileName, nLength - 1)
            '# Si le chemin ne commence pas par '.', et que les attributs de l'element listé
            '# correspondent a ce que l'on cherche...
            If AscW(msName) <> 46 And CBool(mtFileInfo.dwFileAttributes And meRequiredAttributes) Then
                '# l'Item en cours est valide, msName contiendra un nom (fichier ou dossier) valide
                ItemEnCoursValide = True
            End If
        End If
        
    End Function

    '# Recherche et pointe sur le prochain nom (du fichier ou dossier) valide.
    Private Sub RechercheProchainItemValide()
        msName = vbNullString
        Do
            '# on passe a l'element suivant
            If FindNextFile(mhFind, mtFileInfo) = 0 Then
                Exit Do
            ElseIf mhFind > 0 Then
                If ItemEnCoursValide Then Exit Do
            Else
                Exit Do
            End If
        Loop
    End Sub

    '# Renvoie les attributs du fichier
    Public Property Get Attributes() As VbFileAttribute
        Attributes = mtFileInfo.dwFileAttributes
    End Property

    Public Property Get CreationDate() As Date
        CreationDate = FileTimeToDate(mtFileInfo.ftCreationTime)
    End Property

    Public Property Get LastAccessDate() As Date
        LastAccessDate = FileTimeToDate(mtFileInfo.ftLastAccessTime)
    End Property

    Public Property Get LastWriteDate() As Date
        LastWriteDate = FileTimeToDate(mtFileInfo.ftLastWriteTime)
    End Property

    Public Property Get FileSize() As Variant
    Dim xnCurValue(1) As Long
    Dim nCurValue As Currency
        '# Sacré fichier ! sa taille dépasse les 4Go...
        If mtFileInfo.nFileSizeHigh Then
            '# On récupère la taille dans deux longs
            xnCurValue(0) = mtFileInfo.nFileSizeLow
            xnCurValue(1) = mtFileInfo.nFileSizeHigh
            '# On place le tout dans un Currency
            CopyMemory nCurValue, xnCurValue(0), 8
            '# Que l'on redonne en sortie
            FileSize = nCurValue
        Else
            '# Taille < 4Go. Un long suffit : on renvoie directement nFileSizeLow
            FileSize = mtFileInfo.nFileSizeLow
        End If
    End Property

    '# Permet de passer à l'element suivant dans la recherche.
    Public Sub MoveNext()
        Call RechercheProchainItemValide
    End Sub

    '# Est-ce que la recherche est terminée ?
    Public Property Get EOF() As Boolean
        EOF = (msName = vbNullString)
    End Property

    Private Sub Class_Terminate()
        '# On clot la recherche
        If mhFind > 0 Then FindClose mhFind
    End Sub

  • signaler à un administrateur
    Commentaire de asimengo le 02/08/2007 19:12:09

    RECTIFICATION
    -------------

    Private Function ItemEnCoursValide() As Boolean
    Dim nLength As Long
        
        nLength = InStr(mtFileInfo.cFileName, vbNullChar)
        If nLength Then
            msName = Left$(mtFileInfo.cFileName, nLength - 1)
            '# Si le chemin ne commence pas par '.', et que les attributs de l'element listé
            '# correspondent a ce que l'on cherche...
            If AscW(msName) <> 46 And CBool(mtFileInfo.dwFileAttributes And meRequiredAttributes) Then
                '# l'Item en cours est valide, msName contiendra un nom (fichier ou dossier) valide
                ItemEnCoursValide = True
            Else
                msName = vbNullString
            End If
        End If
        
    End Function

  • signaler à un administrateur
    Commentaire de Renfield le 02/08/2007 21:53:31 administrateur CS

    R.A.S., a part que tu fais FindNextFile sans vérifier mhFind

    sinon c'est Ok. Coté traitement, tout se passe au final comme dans mon code...

  • signaler à un administrateur
    Commentaire de asimengo le 02/08/2007 22:09:10

    J'ai laissé exprès, pensant reduire les tests pour les cas de recherche d'item valide afin d'accélérer un peu et je pensais que FindNextFile(mhFind, mtFileInfo) reverrait une valeur <=0 si mhFind<=0, mais je n'ai pas testé.
    Merci d'avoir disposé de ton temps pour regarder mon commentaire, je pense que ta source m'aidera et plus d'un comme dab.

  • signaler à un administrateur
    Commentaire de Charles Racaud le 03/08/2007 12:27:09

    Ouah, c'est bien rapide.
    Mais quand je liste les fichiers contenant des caractères Unicode dans leurs noms.
    Dir ne trouve rien.
    Fso les trouve mais remplace par des ? (normal VB gère pas l'Unicode).
    CDir ne trouve rien.
    Il serait pas mal d'avoir au moins des ? à la place des caractères Unicode comme le fait la méthode par fso.
    __
    Kenji

  • signaler à un administrateur
    Commentaire de Renfield le 03/08/2007 15:08:24 administrateur CS

    c'est réglé, Charles Racaud, bonne remarque.
    J'utilise mainenant l'API Unicode

  • signaler à un administrateur
    Commentaire de Charles Racaud le 03/08/2007 16:53:43

    Ha, désolé de te l'annoncer, mais ca ne marche toujours pas.
    J'ai des noms de fichier contenant des hiraganas et katakanas (caractères japonais), la liste est hélas toujours vide.
    __
    Kenji

  • signaler à un administrateur
    Commentaire de Renfield le 03/08/2007 21:27:58 administrateur CS

    :/ testé avec un caractère unicode au pif, ca passait :(

  • signaler à un administrateur
    Commentaire de hpfx le 18/11/2007 18:53:47

    Salut,
    juste une remarque,
    si on retire le calcul de la taille du fichier et de la date, pour moi Dir() passe devant CDir (et Dir2 et autres)
    en fait si vous ne voulez que les nom des fichiers le plus rapidement possible, il suffit d'utiliser Dir().
    Je n'y croyais pas moi même, j'ai passé la journée à tester les fameux codes de mvps.org/vbnet et je ne comprenais pas pourquoi mes bench me montrait que dir() est 2 fois plus rapide.

    avec ton code (qui implemente dejà le bench) il suffit de commenter un bout de code là... (apres le name)
    .AddItem oDir.Name ' & ">" & oDir.FileSize & ">" & oDir.LastWriteDate
    idem pour les 3 autres, et là... stupefaction!... Dir() explose tout.... (FSO est nul)
    si seulement j'avais sut cela avant, j'aurais gagné une journée... ;)

    ce message d'adresse a ceux qui veulement optimiser leur dir()...

    en tout cas, bravo pour ton code, j'adore.
    Merci.

  • signaler à un administrateur
    Commentaire de Renfield le 19/11/2007 02:55:15 administrateur CS

    Le Doevents présent dans la propriété Name y est pour beaucoup.
    je viens d'optimiser un peu le code, les temps d'execution de Dir et CDir se valent...

    merci de m'avoir incité a revoir la chose ^^

Ajouter un commentaire

Pub



Appels d'offres

CalendriCode

Juillet 2008
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

VS Express FR Gratuit !

VS Express en français et 100% gratuit !

Téléchargements

Logiciels à télécharger sur le même thème :

Boutique

Boutique de goodies CodeS-SourceS