Page 1 sur 1

Routine pour entrer dans tous les répertoires

Publié : sam. 09/mai/2020 21:52
par SPH
Salut,

je passe par là en constatant que le forum est calme en ce moment.
Alors, je vais poser une question simple : je cherche une routine qui permette de rentrer dans tous les répertoires (et lister tous les fichiers) :!:

Par exemple, si j'ai 3 repertoires dans c:/amd/, et que j'ai 5 fichiers dans chaque répertoire, comment faire :?:

Je suis sûr que si je cherchais bien, je trouverais mais je profite du forum pour demander...

Merci beaucoup 8)

Re: Routine pour entrer dans tous les répertoires

Publié : sam. 09/mai/2020 23:04
par venom
Salut sph,

Tu aurais pu avoir un minimum de motivation et chercher sur le forum :? :D

Voici un code de falsam un peut modifier qui fait exactement le taf que tu demande. Avec l'utilisation de thread en bonus pour stoper/reprendre le scan.

Code : Tout sélectionner

; By Falsam
; https://www.purebasic.fr/french/viewtopic.php?p=130717#p130717
Enumeration
  #MainForm
  #StartStop
  #ListFolder
  #CountFiles
EndEnumeration

Global CountFiles.i
Global Chemin$ = PathRequester("Répertoire a scanner", GetUserDirectory(#PB_Directory_Desktop))

;Parcourir un dossier (Fonction recurssive by Flype il me semble)
Procedure.s ParseDirectory(folder.s, id.l = 0)
  If Right(folder, 1) <> "\"
    folder + "\"
  EndIf
 
  If ExamineDirectory(id, folder, "*.*")
    While NextDirectoryEntry(id) And GetGadgetData(#StartStop)=#True
      If DirectoryEntryName(id) <> "." And DirectoryEntryName(id) <> ".."
        AddGadgetItem(#ListFolder,-1, folder +Chr(10)+DirectoryEntryName(id))
        countFiles+1
        SetGadgetText(#CountFiles, Str(CountFiles))
        If DirectoryEntryType(id) = #PB_DirectoryEntry_Directory
          ParseDirectory(folder + DirectoryEntryName(id), id + 1)
        EndIf
      EndIf
    Wend
    FinishDirectory(id)
  EndIf
EndProcedure

Procedure StartThread(*Value)
  ClearGadgetItems(#ListFolder)
  CountFiles=0
  ParseDirectory(Chemin$)
  While GetGadgetData(#StartStop)=#True
  Wend
EndProcedure

Procedure MainFormShow()
  OpenWindow(#MainForm,0,0,800,600,"Lecture d'un dossier(Thread)",#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  TextGadget(#PB_Any, 10, 10, 50, 20, "Fichier(s)")
  TextGadget(#CountFiles, 100, 10, 80, 20, "0")
  ListIconGadget(#ListFolder, 10, 30, 780,530, "Dossier", 380)
  AddGadgetColumn(#ListFolder, 1, "Fichier",390)
  ButtonGadget(#StartStop, 10, 570, 780, 20, "Start/Stop")
EndProcedure

MainFormShow()

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #StartStop
          If GetGadgetData(#StartStop)=#False
            SetGadgetData(#StartStop, #True) ;Indiquer au bouton qu'il est actif
            CreateThread(@StartThread(), 0)
          Else
            SetGadgetData(#StartStop, #False)
          EndIf
         
      EndSelect
     
    Case #PB_Event_SizeWindow
      WWidth=WindowWidth(#MainForm)
      Wheight=WindowHeight(#MainForm)
      ResizeGadget(#ListFolder, #PB_Ignore, #PB_Ignore , WWidth-10, Wheight-75)
      ResizeGadget(#StartStop, (WWidth/2)-35, Wheight-30 , #PB_Ignore, #PB_Ignore)
     
    Case #PB_Event_CloseWindow
      End
  EndSelect
ForEver





@++

Re: Routine pour entrer dans tous les répertoires

Publié : dim. 10/mai/2020 6:42
par SPH
Merci à toi :P

EDIT : quand on est dans un répertoire, si il y a des répertoires dans celui-ci (et des fichiers), comment savoir combien pèse le répertoire ?

Re: Routine pour entrer dans tous les répertoires

Publié : dim. 10/mai/2020 7:40
par venom
Un répertoire n'a pas de poids. Le mieux reste l'addition de tous les fichiers a l'intérieur.






@++

Re: Routine pour entrer dans tous les répertoires

Publié : dim. 10/mai/2020 7:47
par SPH
venom a écrit :Un répertoire n'a pas de poids. Le mieux reste l'addition de tous les fichiers a l'intérieur.
Ca va etre dur si les fichiers sont dans un 8eme repertoire :idea:

Je posais la question car windows sait le faire (clic droit sur un répertoire puis propriété) :!:

Re: Routine pour entrer dans tous les répertoires

Publié : dim. 10/mai/2020 7:55
par venom
Oui. Et bien fait clic droit sur un gros dossier, tu vois bien que ton chiffre augmente devant tes yeux. (Donc windows liste et additionne les fichiers a l'intérieur ) :wink:






@++

Re: Routine pour entrer dans tous les répertoires

Publié : mer. 13/mai/2020 10:52
par kernadec
bjr SPH
pour cette tache on peut utiliser un couteau Suisse avec RunPrograme (Winmerge.exe)
gratuit qu'on trouve partout et en français

Cordialement

Re: Routine pour entrer dans tous les répertoires

Publié : mer. 13/mai/2020 13:06
par Marc56
Ca va etre dur si les fichiers sont dans un 8eme repertoire
Il suffit d'additionner les DirectoryEntrySize(id) qui donne la taille du fichier

Voila le programme de Falsam auquel j'ai ajouté le total des répertoires
(voir lignes avec --- Added)

Code : Tout sélectionner

; By Falsam
; https://www.purebasic.fr/french/viewtopic.php?p=130717#p130717
Enumeration
    #MainForm
    #StartStop
    #ListFolder
    #CountFiles
EndEnumeration

Global CountFiles.i
Global sizeFiles.i ; --- Added
Global Chemin$ = PathRequester("Répertoire a scanner", GetUserDirectory(#PB_Directory_Desktop))

;Parcourir un dossier (Fonction recurssive by Flype il me semble)
Procedure.s ParseDirectory(folder.s, id.l = 0)
    If Right(folder, 1) <> "\"
        folder + "\"
    EndIf
    
    If ExamineDirectory(id, folder, "*.*")
        While NextDirectoryEntry(id) And GetGadgetData(#StartStop)=#True
            If DirectoryEntryName(id) <> "." And DirectoryEntryName(id) <> ".."
                AddGadgetItem(#ListFolder,-1, folder +Chr(10)+DirectoryEntryName(id))
                countFiles+1
                sizeFiles + DirectoryEntrySize(id) ; --- Added
                                                  ; SetGadgetText(#CountFiles, Str(CountFiles))
                ; --- Added
                SetGadgetText(#CountFiles, Str(CountFiles) + "               Total: " + FormatNumber(sizeFiles/1024, 2) + " ko")
                If DirectoryEntryType(id) = #PB_DirectoryEntry_Directory
                    ParseDirectory(folder + DirectoryEntryName(id), id + 1)
                EndIf
            EndIf
        Wend
        FinishDirectory(id)
    EndIf
EndProcedure

Procedure StartThread(*Value)
    ClearGadgetItems(#ListFolder)
    CountFiles=0
    ParseDirectory(Chemin$)
    While GetGadgetData(#StartStop)=#True
    Wend
EndProcedure

Procedure MainFormShow()
    OpenWindow(#MainForm,0,0,800,600,"Lecture d'un dossier(Thread)",#PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
    TextGadget(#PB_Any, 10, 10, 50, 20, "Fichier(s)")
    TextGadget(#CountFiles, 100, 10, 300, 20, "0") ; --- Added 30 -> 300
    ListIconGadget(#ListFolder, 10, 30, 780,530, "Dossier", 380)
    AddGadgetColumn(#ListFolder, 1, "Fichier",390)
    ButtonGadget(#StartStop, 10, 570, 780, 20, "Start/Stop")
EndProcedure

MainFormShow()

Repeat
    Select WaitWindowEvent()
        Case #PB_Event_Gadget
            Select EventGadget()
                Case #StartStop
                    If GetGadgetData(#StartStop)=#False
                        SetGadgetData(#StartStop, #True) ;Indiquer au bouton qu'il est actif
                        CreateThread(@StartThread(), 0)
                    Else
                        SetGadgetData(#StartStop, #False)
                    EndIf
                    
            EndSelect
            
        Case #PB_Event_SizeWindow
            WWidth=WindowWidth(#MainForm)
            Wheight=WindowHeight(#MainForm)
            ResizeGadget(#ListFolder, #PB_Ignore, #PB_Ignore , WWidth-10, Wheight-75)
            ResizeGadget(#StartStop, (WWidth/2)-35, Wheight-30 , #PB_Ignore, #PB_Ignore)
            
        Case #PB_Event_CloseWindow
            End
    EndSelect
ForEver
:wink:

Re: Routine pour entrer dans tous les répertoires

Publié : mer. 13/mai/2020 14:51
par SPH
kernadec a écrit :bjr SPH
pour cette tache on peut utiliser un couteau Suisse avec RunPrograme (Winmerge.exe)
gratuit qu'on trouve partout et en français

Cordialement
Je n'ai AUCUNE idée de ce que c'est et de la façon de l'utiliser dans PB ! Mais : merci quand même :!:

Merci Marc, tu assures ces temps-ci 8)

Re: Routine pour entrer dans tous les répertoires

Publié : mer. 13/mai/2020 18:10
par Ollivier
Il me semble qu'effectivement, les tailles des dossiers de fichiers restent des valeurs précalculées.

En gros, on ne peut savoir la taille d'un dossier de fichiers (sans sous-dossier(s) ) qu'après un examen terminé de ce dossier.

Ceci, parce qu'il me semble que dans une structure :

Code : Tout sélectionner

C: / Dossier / SousDossier / Fichier.TXT
Dans ce cas général, si on ajoute un octet de stocké dans le fichier texte, il faudrait que l'OS ajoute la valeur 1 dans chaque taille des dossiers parent, du dossier parent, jusqu'au dossier racine.

Or, un fichier de type dossier, il me semble que ça occupe toujours le même gabarit, sans une spécification de taille occupée par les données sous-jacentes.

Donc, à moins d'un système qui se mette à jour automatiquement, c'est à l'explorateur de fichiers et dossiers de bien évaluer la taille totale en octets et en "secteurs" occupée par tous les fichiers.