Page 1 sur 1

Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : lun. 12/sept./2016 9:51
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:

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 14/sept./2016 12:15
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)

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 14/sept./2016 12:31
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.

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 14/sept./2016 15:58
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:

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 07/déc./2016 8:29
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

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 07/déc./2016 11:15
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)

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 07/déc./2016 11:49
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.

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 07/déc./2016 12:11
par Ar-S
Merci Mesa, très bien ce code.
367016 files scanned in 4.770s

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 07/déc./2016 14:30
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...

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 07/déc./2016 15:10
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:

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : mer. 07/déc./2016 19:11
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é ;)

Re: Ajout de #PB_FileSystem_Recursive à ExamineDirectory()

Publié : jeu. 08/déc./2016 17:10
par Kwai chang caine
Zorro a écrit :donc je suis un peu lent là
T'avais peut être pas trouvé la deuxieme ??? :mrgreen:
Image