Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Vous avez une idée pour améliorer ou modifier PureBasic ? N'hésitez pas à la proposer.
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Marc56 »

Hello Fred,

La commande CopyDirectory() contient une option #PB_FileSystem_Recursive très utile et rapide.

:idea: Pourrais-tu ajouter cette même option à ExamineDirectory() ?
Je suppose que c'est cette commande qui constitue la liste des fichiers qui est ensuite utilisée par NextDirectoryEntry() ?
Ainsi la commande NextDirectoryEntry() utiliserait tous les fichiers et pas seulement ceux du répertoire en cours.

Il existe de nombreux exemples qui fonctionnent bien, mais une extension de la commande interne serait un gros plus.
En effet, beaucoup d'applications pro (ex: domaine du middleware par exemple) effectuent des opérations sur des répertoires complets.
C'est utile aussi pour la compression de fichiers puisque PB gère cela.

D'autres options pourraient être ajoutées:
  • Option pour la prise compte ou non des fichiers/répertoires par attributs (système, cachés, archive)
  • Option de suivi des liens symboliques (de répertoires et/ou de fichier) (sinon simple copie du fichier .lnk)
  • Retour d'info sur le nombre de fichiers qui correspond au masque.
Merci
:wink:
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par JohnJohnsonSHERMAN »

Exellente idée ! Je plussoie, flemmard comme je suis, ca m'évitera de coder un explorateur récursif pour la gestion de playlistes/random music dans ma prochaine version de l'Oscillo :mrgreen:
Ca peut être en effet intéressant, mais comment différencier les fichiers situés dans des sous répertoires?
ce serait bien de pouvoir lister tous les fichiers contenus dans une arborescence de répertoires, via un chemin relatif au répertoire pére : exemple (on imagine avoir utilisé la fonction sur un répertoire contenant de la musique, et affiché les fichiers dans le debug):

Code : Tout sélectionner

###DEBUG###
music.wav
intro.mp3
intro2.mp3
bk_slow.mp3
sherman_intro.wav
California dreamin'.wav
Surfing USA.wav
\Electro\Automatic (part1).mp3
\Electro\Automatic (part2).mp3
\Musiques de films\Flic de Beverley OST.mp3
\Musiques de films\Battlesip - The Art of War.wav
\Musiques de films\Crimpson Tide\Main Theme.wav
\World of Warships\A day for Freedom.wav
\World of Warships\Big Ships.wav
\World of Warships\Pahi Nui.wav
\World of Warships\extract\jingles\victory\mai_tai.ogg 
Comme on le constate, il faudrai renvoyer pour les fichiers situés plus bas dans l'arborescence le ou les répertoires qui les séparent du répertoire pére. Comme ca on saurait directement où aller chercher tel ou tel fichier.

[HS]petite question en passant : existe t-il une fonction qui renvoie la taille totale de tout ce que contient un répertoire? [/HS]

(précision: musiques données a tire indicatif)
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par falsam »

JohnJohnsonSHERMAN a écrit :ca m'évitera de coder un explorateur récursif
Regarde cet exemple.
http://www.purebasic.fr/french/viewtopi ... 17#p130717

Active la gestion des threads dans les options de compilation.

Je le corrigerais car il manque de stabilité quand on ferme la fenêtre sans arrêter le thread.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Marc56 »

En voilà un particulièrement rapide et qui tient en 25 lignes (mais ne vérifie pas si le répertoire initial est ok)
(J'ai mis l'url où je l'ai trouvé, mais je ne sais pas si c'est l'auteur original)
Auteur: Trond ? http://www.forums.purebasic.com/english ... 33&start=0

Code : Tout sélectionner

Procedure ListFilesRecursive(Dir.s, List Files.s())
  NewList Directories.s()
  If Right(Dir, 1) <> "\"
    Dir + "\"
  EndIf
  D = ExamineDirectory(#PB_Any, Dir, "")
  While NextDirectoryEntry(D)
    Select DirectoryEntryType(D)
      Case #PB_DirectoryEntry_File
        AddElement(Files())
        Files() = Dir + DirectoryEntryName(D)
      Case #PB_DirectoryEntry_Directory
        Select DirectoryEntryName(D)
          Case ".", ".."
            Continue
          Default
            AddElement(Directories())
            Directories() = Dir + DirectoryEntryName(D)
        EndSelect
    EndSelect
  Wend
  FinishDirectory(D)
  ForEach Directories()
    ListFilesRecursive(Directories(), Files())
  Next
EndProcedure

NewList F.s()
ListFilesRecursive("C:\Program Files\PureBasic\Examples\", F())
ForEach F()
  Debug F()
Next
Sinon, la méthode shell avec RunProgram (Windows)

Code : Tout sélectionner

Dir /bs "C:\Program Files\PureBasic\Examples\" > liste.txt
:wink:
poshu
Messages : 1138
Inscription : sam. 31/juil./2004 22:32

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par poshu »

Code : Tout sélectionner

Procedure ProcessFolder(directory.s)
   Protected directoryID
   directoryID = ExamineDirectory(#PB_Any,directory,"*.*")
   While NextDirectoryEntry(directoryID)
      If DirectoryEntryType(directoryID) = #PB_DirectoryEntry_File
         Debug directory+DirectoryEntryName(directoryID)
         ; le code de traitement des fichiers va là.
      Else
         If DirectoryEntryName(directoryID) <> "." Or DirectoryEntryName(directoryID) <> ".."
            ProcessFolder(directory+DirectoryEntryName(directoryID)+"/")
         EndIf
      EndIf
    Wend
    FinishDirectory(directoryID)
EndProcedure

ProcessFolder(#PB_Compiler_Home+"Examples\")
Plus court et efficace :
  • Faire un select sur deux entrées, c'est lent comparé à un if.
  • pourquoi stocker tout ça dans une liste chaînée? C'est lent et inefficace, autant directement traiter le document dans la fonction
  • "\" c'est windows only, "/" c'est tous les OS
Dernière modification par poshu le ven. 03/févr./2017 22:58, modifié 1 fois.
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Kwai chang caine »

Poshu a écrit :"\" c'est windows only, "/" c'est tous les OS
Je ne savais pas qu'on pouvait utiliser "/" sous windows 8O
Effectivement, plus court...je vois pas :D
Merci du partage 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Mesa
Messages : 1097
Inscription : mer. 14/sept./2011 16:59

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Mesa »

Dans de rares cas, un dossier trop volumineux peut dépasser les limites d'affichage d'un treeview ou d'un listview. Pour éviter ce cas, une liste est plus sûr même si c'est plus lent.

Pour info le code de ts soft ci-dessous fait le job ultra rapidement sur mon pc (j'ai un ssd), il fait la liste de 154100 fichiers en 754ms !

http://www.forums.purebasic.com/english ... 9ba8d49508

Code : Tout sélectionner

EnableExplicit

Prototype clbSearchFile(lType.l, sName.s)

Procedure BrowseDirectory(sPath.s, *pClbFound = 0)
  Protected lDicID.l, qFiles.q, sDirName.s
  Static pCallBack.clbSearchFile
  
  If (Right(sPath, 1) <> "\"): sPath + "\"  : EndIf
  If (Not pCallBack): pCallBack = *pClbFound: EndIf
  
  lDicID = ExamineDirectory(#PB_Any, sPath, "*.*")
  If lDicID
    While NextDirectoryEntry(lDicID)
      qFiles + 1
      
      If DirectoryEntryType(lDicID) =  #PB_DirectoryEntry_File
        If Not pCallBack(1, sPath + DirectoryEntryName(lDicID))
          Break
        EndIf
        
      Else
        sDirName = DirectoryEntryName(lDicID)
        
        If (sDirName <> ".") And (sDirName <> "..")
          
          If pCallBack(2, sPath + sDirName)   
            qFiles + BrowseDirectory(sPath + sDirName)
          Else
            Break
          EndIf
        EndIf
      EndIf
    Wend
    
    FinishDirectory(lDicID)
    ProcedureReturn qFiles
  EndIf
EndProcedure

NewList Files.s()

Procedure MyFiles(Type, Name$)
  Shared Files.s()
  If Type = 2
    ProcedureReturn #True
    
  Else
    AddElement(Files())
    Files() = Name$
    ProcedureReturn #True
  EndIf
EndProcedure

Define count, time, time2
time = ElapsedMilliseconds()
count = BrowseDirectory("C:\", @MyFiles())
time2 = ElapsedMilliseconds() - time

MessageRequester(Str(count) + "Files", "scanned in: " + Str(time2) + "ms")

; ForEach Files()
;   Debug Files()
; Next
M.
Avatar de l’utilisateur
Ar-S
Messages : 9476
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Ar-S »

Merci Mesa, très bien ce code.
367016 files scanned in 4.770s
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Kwai chang caine »

Bien sûr vous avez tous des machines de guerre :roll:
Moi avec mon "super" LENOVO portable W7 ou y'a même pas une led d'activité DD (on arrête pas les économies) :?
480974 files scanned in 195.948 s
Donc tout dépend surtout de la machine et de son DD...
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Zorro »

arf !

Image

en parralelle je converti en batch des gros *.dds en *.png (pour mon simulateur de Vol Xplane 10 )
donc je suis un peu lent là :mrgreen:
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
JohnJohnsonSHERMAN
Messages : 648
Inscription : dim. 13/déc./2015 11:05
Localisation : Allez, cherche...
Contact :

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par JohnJohnsonSHERMAN »

322993 Files scanned in: 46280ms (46,28sec)
Un peu lent ^^ Mais bon vu le nombre de fichiers scannés, on va conclure que mon DD est super lent, ce qui est bien le cas :(
En tout cas trés bon code, exellent même. Archivé direct en sureté ;)
"Le bug se situe entre la chaise et le clavier"
Votre expert national en bogage et segfaults.

CPU : AMD A8 Quad core - RAM 8Gb - HDD 2To
  • Windows 10 x64 - PB 5.61 x64
  • Linux Ubuntu 16.04 LTS x64 (dual boot) - PB pas encore réinstallé
Avatar de l’utilisateur
Kwai chang caine
Messages : 6962
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Message par Kwai chang caine »

Zorro a écrit :donc je suis un peu lent là
T'avais peut être pas trouvé la deuxieme ??? :mrgreen:
Image
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Répondre