9
votes

Comment rechercher un fichier via tous les sous-répertoires de Delphes

J'ai implémenté ce code dans Delphi, il recherchera le fichier ou le nom donné, mais il omet de rechercher tous les sous-répertoires. Comment cela peut-il être fait?

code: xxx


0 commentaires

5 Réponses :


12
votes

Si vous n'avez pas besoin de filetage, le moyen le plus simple est celui-ci: xxx


5 commentaires

Avis en particulier deux choses importantes: la fonction FindClose est appelée à partir d'une section enfin et tous les appels vers éléments.add sont situés entre Articles.Beginupdate et Articles.endUpdate .


Il convient de noter que cette approche utilise la récursivité. Cela ne serait pas évident pour quelqu'un qui pose cette question, s'ils n'avaient pas déjà eu de récursion à l'esprit. Je vais ajouter un commentaire au code, pointez ceci.


Pouvez-vous expliquer le code, de petites choses comme Why FindFirst (inclusetringbackslash (Dir) + '. ' et si (sr.attr et fadirectory) = 0?


@sunandan: (1) includetringbackslash est juste une fonction qui ajoute un \ caractère à la fin d'une chaîne si elle n'est pas déjà terminée par un tel caractère. Et si dir est c: \ utilisateurs ? Ensuite, nous rechercherions c: \ users *. * qui ne fonctionne pas, mais avec l'aide de includetringbackslash , nous recherchons plutôt c: \ Utilisateurs \ *. * qui fonctionne. (2) sr.attr est un bitfield, c'est-à-dire un numéro binaire dans lequel chaque chiffre est soit 1 ou 0 qui vous indique quelque chose d'intéressant. Le cinquième chiffre de la droite est 0 ou 1 selon si le fichier trouvé est un ...


répertoire ou non. Fadirectory est 10000 en binaire. Ainsi, sr.attr et fadirectory n'est pas zéro si et uniquement si le fichier trouvé est un répertoire. Par conséquent, si (sr.attr et fadirectory) = 0 puis doit être lu comme "si le fichier trouvé n'est pas un répertoire", et dans ce cas, nous ajoutons le fichier à la liste de liste. D'autre part, si le fichier est un répertoire (mais pas le répertoire '..' ou '' qui existe dans (presque) dans chaque répertoire et signifie simplement le répertoire précédent et actuel, respectivement), nous appelons la fonction < Code> addallfilesIndr à nouveau avec ce nouveau répertoire.




27
votes

Avec Delphi Xe et UP, vous pouvez consulter IOUTILS.PAS:

TDirectory.GetFiles('C:\', '*.dll', TSearchOption.soAllDirectories);


1 commentaires

J'ai utilisé Delphi 2009 depuis de nombreuses années. Lorsque j'ai mis à niveau vers XE2, puis à XE8, vous n'avez pas réalisé qu'ils ont été ajoutés. +1




1
votes

Quand j'ai besoin de faire astuces code> comme des méthodes protégées de remplacement, j'ai tendance à utiliser une solution générique au problème ... Je fais un piratage à la classe.

Voici comment le faire Avec tdirectorylistbox code>. p>

sur chaque formulaire, vous devez utiliser ce formulaire piraté code> tdirectorylistbox code> Ajouter UnittDirectoryListbox_withHiddridaDidDeSystembeters Code > à l'interface utilise code>, de cette façon le formulaire utilisera le packed code> tdirectorylistbox code>. p>

Créer un fichier appelé UnittdirectoryListbox_withHiddridaDidDeDsystemIndLesfolders.pas code> sur votre dossier Proyect. P>

Mettez ce texte à l'intérieur de ce fichier (je vais vous expliquer plus tard ce que j'ai fait): P>

unit unitTDirectoryListbox_WithHiddenAndSystemFolders;

interface

uses
    Windows
   ,SysUtils
   ,Classes
   ,FileCtrl
   ;

type TDirectoryListbox=class(FileCtrl.TDirectoryListbox)
   private
     FPreserveCase:Boolean;
     FCaseSensitive:Boolean;
   protected
     function ReadDirectoryNames(const ParentDirectory:String;DirectoryList:TStringList):Integer;
     procedure BuildList;override;
   public
     constructor Create(AOwner:TComponent);override;
     destructor Destroy;override;
     property PreserveCase:Boolean read FPreserveCase;
     property CaseSensitive:Boolean read FCaseSensitive;
end;

implementation

constructor TDirectoryListbox.Create(AOwner:TComponent);
begin
     inherited Create(AOwner);
end;

destructor TDirectoryListbox.Destroy;
begin
     inherited Destroy;
end;

function TDirectoryListbox.ReadDirectoryNames(const ParentDirectory:String;DirectoryList:TStringList):Integer;
var
  TheCount,Status:Integer;
  SearchRec:TSearchRec;
begin
     TheCount:=0;
     Status:=FindFirst(IncludeTrailingPathDelimiter(ParentDirectory)+'*.*',faDirectory or faHidden or faSysFile,SearchRec);
     try
        while 0=Status
        do begin
                if faDirectory=(faDirectory and SearchRec.Attr) 
                then begin
                          if   ('.'<>SearchRec.Name)
                            and
                               ('..'<>SearchRec.Name)
                          then begin
                                    DirectoryList.Add(SearchRec.Name);
                                    Inc(TheCount);
                               end;
                     end;
                Status:=FindNext(SearchRec);
           end;
     finally
            FindClose(SearchRec);
     end;
     ReadDirectoryNames:=TheCount;
end;

procedure TDirectoryListBox.BuildList;
var
  TempPath: string;
  DirName: string;
  IndentLevel, BackSlashPos: Integer;
  VolFlags: DWORD;
  I: Integer;
  Siblings: TStringList;
  NewSelect: Integer;
  Root: string;
begin
  try
    Items.BeginUpdate;
    Items.Clear;
    IndentLevel := 0;
    Root := ExtractFileDrive(Directory)+'\';
    GetVolumeInformation(PChar(Root), nil, 0, nil, DWORD(i), VolFlags, nil, 0);
    FPreserveCase := VolFlags and (FS_CASE_IS_PRESERVED or FS_CASE_SENSITIVE) <> 0;
    FCaseSensitive := (VolFlags and FS_CASE_SENSITIVE) <> 0;
    if (Length(Root) >= 2) and (Root[2] = '\') then
    begin
      Items.AddObject(Root, OpenedBMP);
      Inc(IndentLevel);
      TempPath := Copy(Directory, Length(Root)+1, Length(Directory));
    end
    else
      TempPath := Directory;
    if (Length(TempPath) > 0) then
    begin
      if AnsiLastChar(TempPath)^ <> '\' then
      begin
        BackSlashPos := AnsiPos('\', TempPath);
        while BackSlashPos <> 0 do
        begin
          DirName := Copy(TempPath, 1, BackSlashPos - 1);
          if IndentLevel = 0 then DirName := DirName + '\';
          Delete(TempPath, 1, BackSlashPos);
          Items.AddObject(DirName, OpenedBMP);
          Inc(IndentLevel);
          BackSlashPos := AnsiPos('\', TempPath);
        end;
      end;
      Items.AddObject(TempPath, CurrentBMP);
    end;
    NewSelect := Items.Count - 1;
    Siblings := TStringList.Create;
    try
      Siblings.Sorted := True;
        { read all the dir names into Siblings }
      ReadDirectoryNames(Directory, Siblings);
      for i := 0 to Siblings.Count - 1 do
        Items.AddObject(Siblings[i], ClosedBMP);
    finally
      Siblings.Free;
    end;
  finally
    Items.EndUpdate;
  end;
  if HandleAllocated then
    ItemIndex := NewSelect;
end;

end.


1 commentaires

Je ne suis pas sûr de quelle question que vous répondez, mais ce n'est pas celui-ci, qui ne demande rien de tdirectorylistbox ou de modification de méthodes ou de propriétés de composants, ni rien sur des fichiers cachés ou système. Celui-ci pose des questions sur les fichiers itérus des sous-répertoires.