K

- Base de connaissances

Accueil > API WINDOWS > FindFirstFile

FindFirstFile

mardi 10 août 2010, par webmestre

Fichier DLL : kernel32.dll

Prototype VB6/VBA :

Declare Function FindFirstFile Lib "kernel32.dll" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long

Prototype VB.NET :

Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As Integer

Cette fonction permet de parcourir un répertoire pour retrouver un ou plusieurs fichiers. La variable lpFileName doit contenir le chemin du répertoire ainsi que le filtre de fichier à rechercher (Par exemple : le masque *.txt pour rechercher les fichiers au format texte ou *.* pour récupérer tous les fichiers d’un répertorie).

La valeur retournée par la fonction est un "handle" (le pseudo équivalent d’un pointeur) de recherche qui permet de parcourir le "buffer" des fichiers répondant au masque au moyen de l’API FindNextFile .

Une fois, les opérations de recherche terminées, ce "handle" permet de libérer les ressources au moyen de l’API FindClose .

Il est a noté que si le "handle" de retour vaut zéro, cela signifie que la fonction a échoué.

Le résultat de la recherche de l’API FindFirstFile ou FindNextFile est renvoyée dans une structure WIN32_FIND_DATA.

L’exemple de code, présenté ci-dessous, propose une implémentation des APIs FindFirstfile, FindNextFile et FindClose. Il permet de rechercher un fichier ou plusieurs fichiers dans un répertoire ou sous-répertoire. Le résultat est un tableau contenant les informations trouvées sur le/les fichiers trouvés.

En VB/VBA cela donne :

Option Explicit
'----------------------------------------
'------Déclarations propres aux API------
'----------------------------------------
'---Les constantes---
Private Const MAX_PATH = 260
Private Const INVALID_HANDLE_VALUE = -1
Private Const FILE_ATTRIBUTE_READONLY = &H1
Private Const FILE_ATTRIBUTE_HIDDEN = &H2
Private Const FILE_ATTRIBUTE_SYSTEM = &H4
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const FILE_ATTRIBUTE_ARCHIVE = &H20
Private Const FILE_ATTRIBUTE_NORMAL = &H80
Private Const FILE_ATTRIBUTE_TEMPORARY = &H100
Private Const FILE_ATTRIBUTE_COMPRESSED = &H800
'---Les API---
Private Declare Function FindFirstFile Lib "kernel32.dll" Alias "FindFirstFileA" (ByVal lpFileName As String, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindNextFile Lib "kernel32.dll" Alias "FindNextFileA" (ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32.dll" (ByVal hFindFile As Long) As Long
'---Les types---
Private Type FILETIME
    dwLowDateTime   As Long
    dwHighDateTime  As Long
End Type
Private Type WIN32_FIND_DATA
    dwFileAttributes    As Long
    ftCreationTime      As FILETIME
    ftLastAccessTime    As FILETIME
    ftLastWriteTime     As FILETIME
    nFileSizeHigh       As Long
    nFileSizeLow        As Long
    dwReserved0         As Long
    dwReserved1         As Long
    cFileName           As String * MAX_PATH
    cAlternate          As String * 14
End Type
'----------------------------------------------
'------Déclarations propres à la fonction------
'----------------------------------------------
Private Type TYPE_ListeFichiers
    Info_Fichiers() As WIN32_FIND_DATA
    Chemins()       As String
    Fichiers()      As String
    Nombre          As Long
End Type
'----------------------------------------------------------------------------------------------
'------Procédure recherchant les fichiers (MasqueFichier) dans le répertoire (Repertoire)------
'------de façon récursive ou non (= dans les sous-répertoires ou non)                    ------
'----------------------------------------------------------------------------------------------
Private Sub RechercherFichiers(Repertoire As String, MasqueFichier As String, Fichiers As TYPE_ListeFichiers, Optional bRecursif As Boolean = True, Optional bInitialisation As Boolean = True)
    '---Déclaration des variables---
    Dim lpFindFileData  As WIN32_FIND_DATA
    Dim hFindFile       As Long
    Dim lDebut          As Long
    Dim Chemin          As String
    Dim sTmp            As String
   
    '---Initialisation---
    If bInitialisation Then
        ReDim Fichiers.Chemins(0)
        ReDim Fichiers.Fichiers(0)
        ReDim Fichiers.Info_Fichiers(0)
        Fichiers.Nombre = 0
    End If
    lDebut = Fichiers.Nombre + 1
   
    '---Vérification d'usage (Ajout du caractère \ en fin de chaîne si besoin)---
    Chemin = Trim$(Repertoire)
    If Len(Repertoire) > 0 Then
        Chemin = Repertoire & IIf(Mid$(Repertoire, Len(Repertoire)) = "\", "", "\")
    End If
   
    '---Recherche tous les fichiers demandés dans le répertoire Chemin---
    hFindFile = FindFirstFile(Chemin & MasqueFichier, lpFindFileData)
    If hFindFile <> INVALID_HANDLE_VALUE Then
        Do
            ' Mémorise
            Fichiers.Nombre = Fichiers.Nombre + 1
            ReDim Preserve Fichiers.Chemins(Fichiers.Nombre)
            ReDim Preserve Fichiers.Fichiers(Fichiers.Nombre)
            ReDim Preserve Fichiers.Info_Fichiers(Fichiers.Nombre)
            Fichiers.Chemins(Fichiers.Nombre) = Chemin
            Fichiers.Fichiers(Fichiers.Nombre) = Left$(lpFindFileData.cFileName, InStr(1, lpFindFileData.cFileName, Chr$(0)) - 1)
            Fichiers.Info_Fichiers(Fichiers.Nombre) = lpFindFileData
           
            ' Initialise lpFindFileData (Variable texte uniquement)
            lpFindFileData.cAlternate = String$(14, 0)
            lpFindFileData.cFileName = String$(MAX_PATH, 0)
        Loop Until FindNextFile(hFindFile, lpFindFileData) = 0
    End If
    FindClose hFindFile
   
    '---Recherche dans les sous-répertoires du répertoire en cours d'analyse---
    If bRecursif Then
        hFindFile = FindFirstFile(Chemin & "*.*", lpFindFileData)
        If hFindFile <> INVALID_HANDLE_VALUE Then
            Do
                sTmp = Left$(lpFindFileData.cFileName, InStr(1, lpFindFileData.cFileName, Chr$(0)) - 1)
                If ((lpFindFileData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY) And (sTmp <> ".") And (sTmp <> "..") Then
                    Call RechercherFichiers(Chemin & sTmp, MasqueFichier, Fichiers, bRecursif, False)
                End If
            Loop Until FindNextFile(hFindFile, lpFindFileData) = 0
        End If
        FindClose hFindFile
    End If
End Sub

Et, en VB.NET :

Public Module Module_FindFirtsFile
        '----------------------------------------
        '------Déclarations propres aux API------
        '----------------------------------------
        '---Les constantes---
        Private Const MAX_PATH                                  as Short = 260
        Private Const INVALID_HANDLE_VALUE              as Short = -1
        Private Const FILE_ATTRIBUTE_READONLY   as Short = &H1
        Private Const FILE_ATTRIBUTE_HIDDEN     as Short = &H2
        Private Const FILE_ATTRIBUTE_SYSTEM     as Short = &H4
        Private Const FILE_ATTRIBUTE_DIRECTORY  as Short = &H10
        Private Const FILE_ATTRIBUTE_ARCHIVE    as Short = &H20
        Private Const FILE_ATTRIBUTE_NORMAL     as Short = &H80
        Private Const FILE_ATTRIBUTE_TEMPORARY  as Short = &H100
        Private Const FILE_ATTRIBUTE_COMPRESSED as Short = &H800
   
        '---Les types---
        Public Structure FILETIME
        Dim dwLowDateTime  As integer
        Dim dwHighDateTime As integer
    End Structure
   
    Public Structure WIN32_FIND_DATA
        Dim dwFileAttributes As Integer
        Dim ftCreationTime       As FILETIME
        Dim ftLastAccessTime As FILETIME
        Dim ftLastWriteTime  As FILETIME
        Dim nFileSizeHigh    As Integer
        Dim nFileSizeLow         As Integer
        Dim dwReserved0          As Integer
        Dim dwReserved1          As Integer
        <VBFixedString(MAX_PATH), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=MAX_PATH)> Dim cFileName As String
        <VBFixedString(14), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=14)> Dim cAlternate As String
    End Structure
        '---Les API---
    Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As Integer
    Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" (ByVal hFindFile As Integer, ByRef lpFindFileData As WIN32_FIND_DATA) As Integer
    Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Integer) As Integer    
   
        '----------------------------------------------
        '------Déclarations propres à la fonction------
        '----------------------------------------------
        Public Structure  TYPE_ListeFichiers
            dim Info_Fichiers() As WIN32_FIND_DATA
            dim Chemins()       As String
            dim Fichiers()      As String
            dim Nombre          As Long
        End structure
        '----------------------------------------------------------------------------------------------
        '------Procédure recherchant les fichiers (MasqueFichier) dans le répertoire (Repertoire)------
        '------de façon récursive ou non (= dans les sous-répertoires ou non)                    ------
        '----------------------------------------------------------------------------------------------
        Public Sub RechercherFichiers(Repertoire As String, MasqueFichier As String, byref Fichiers As TYPE_ListeFichiers, Optional bRecursif As Boolean = True, Optional bInitialisation As Boolean = True)
            '---Déclaration des variables---
            Dim lpFindFileData  As WIN32_FIND_DATA
            Dim hFindFile       As Integer
            Dim Chemin          As String
            Dim sTmp            As String
            Dim lDebut          As Long
           
            '---Initialisation---
            If bInitialisation Then
                ReDim Fichiers.Chemins(0)
                ReDim Fichiers.Fichiers(0)
                ReDim Fichiers.Info_Fichiers(0)
                Fichiers.Nombre = 0
            End If
            lDebut = Fichiers.Nombre + 1
               
            '---Vérification d'usage (Ajout du caractère \ en fin de chaîne si besoin)---
            Chemin = Trim$(Repertoire)
            If Len(Repertoire) > 0 Then
                Chemin = Repertoire & IIf(Mid$(Repertoire, Len(Repertoire)) = "\", "", "\")
            End If
           
            '---Recherche tous les fichiers demandés dans le répertoire Chemin---
            hFindFile = FindFirstFile(Chemin & MasqueFichier, lpFindFileData)
            If hFindFile <> INVALID_HANDLE_VALUE Then
                Do
                    ' Mémorise
                    Fichiers.Nombre = Fichiers.Nombre + 1
                    ReDim Preserve Fichiers.Chemins(Fichiers.Nombre)
                    ReDim Preserve Fichiers.Fichiers(Fichiers.Nombre)
                    ReDim Preserve Fichiers.Info_Fichiers(Fichiers.Nombre)
                    Fichiers.Chemins(Fichiers.Nombre) = Chemin
                    Fichiers.Fichiers(Fichiers.Nombre) = lpFindFileData.cFileName
                    Fichiers.Info_Fichiers(Fichiers.Nombre) = lpFindFileData
                   
                    ' Initialise lpFindFileData (Variable texte uniquement)
                    lpFindFileData.cAlternate = ""
                    lpFindFileData.cFileName = ""
                Loop Until FindNextFile(hFindFile, lpFindFileData) = 0
            End If
            FindClose(hFindFile)
           
                '---Recherche dans les sous-répertoires du répertoire en cours d'analyse---
            If bRecursif Then
                hFindFile = FindFirstFile(Chemin & "*.*", lpFindFileData)
                If hFindFile <> INVALID_HANDLE_VALUE Then
                    Do
                        sTmp = lpFindFileData.cFileName
                        If ((lpFindFileData.dwFileAttributes And FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY) And (sTmp <> ".") And (sTmp <> "..") Then
                                                RechercherFichiers(Chemin & sTmp, MasqueFichier, Fichiers, bRecursif, False)
                        End If
                    Loop Until FindNextFile(hFindFile, lpFindFileData) = 0
                End If
                FindClose(hFindFile)
            End If
        End sub
End Module

Répondre à cet article

Plan du site | Suivre la vie du site RSS 2.0 | powered by NYSTEK-EDITIONS and NYSTEK-CONSULTING