![]() |
Ordentlicher Dateibaum
Ich möchte einen Dateibaum als Textdatei schreiben, ähnlich wie der von DOS/CMD. (tree /f Path)
Jedoch komme ich nicht weiter, als das pure nacheinander Stapeln der Verzeichnisse und Dateien:
Code:
Verzeichniss
Datei Datei UnterVerzeichnis Datei Datei etc. Was ich machen möchte: Verzeichnis ├─UnterVerzeichnis │ └───Datei └───Datei Danke, für die, die mir helfen würden. |
AW: Ordentlicher Dateibaum
Code:
Edit:
1:Verzeichnis
1:Datei 1:Datei 2:UnterVerzeichnis 2:Datei 2:Datei 3:UnterDingens 3:Datei 1:Verzeichnis2 Guck dir mal den Aufbau von *.cnt Dateien die an einigen *.hlp Dateien dabei sind. Sie speichern ihren Baum in einer ähnlichen Form. Die Zahl gibt die Tiefe an, der Rest ist ein wenig programmieren. |
AW: Ordentlicher Dateibaum
Okay das beduetet ich sollte das Dingen jetzt in ein zweidimensionales Array abspeichern und nacheinander aufrufen? (Zuerst alles von 2, dann 3, dann 4... etc. letzlich 1)
Und wie würde ich das mit den Strichen hinbekommen? :pale: Bei mir sieht es momentan so aus:
Delphi-Quellcode:
//Liste
if FindFirst(Directory + Mask, faAnyFile and not faDirectory, SR) = 0 then try repeat if not ShowExt then SR.Name := ChangeFileExt(SR.Name, ''); if ShowDir then begin //Hier versch. Schreibweisen hin! List.Add(Directory + SR.Name); end else begin //Hier versch. Schreibweisen hin! List.Add(SR.Name); end; until FindNext(SR) <> 0; finally FindClose(SR); end; if WithSubDirs then begin if FindFirst(Directory + '*.*', faAnyFile, SR) = 0 then try repeat if ((SR.attr and faDirectory) = faDirectory) and (SR.Name <> '.') and (SR.Name <> '..') then ScanDir(Directory + SR.Name + '\'); until FindNext(SR) <> 0; finally FindClose(SR); end; end; end; begin List.BeginUpdate; try if ClearList then List.Clear; if Directory = '' then Exit; if Directory[Length(Directory)] <> '\' then Directory := Directory + '\'; ScanDir(Directory); finally List.EndUpdate; end; end; |
AW: Ordentlicher Dateibaum
Du rufst ScanDir ja rekursiv auf. Nun brauchst du der Methode doch nur noch einen zusätzlichen Parameter mitgeben, der die Verzeichnistiefe angibt bzw. gleich den voranzustellenden Text. So ca.:
Delphi-Quellcode:
Theoretisch könntest du aus dem Verzeichnis auch direkt die Verzeichnistiefe jedes Mal ermitteln, aber das ist unnötig viel Aufwand.
procedure ScanDir(const APrefix, APath: string);
begin ... List.Add(APrefix + SR.Name); ... ScanDir(APrefix + ' ', Directory + SR.Name + '\'); |
AW: Ordentlicher Dateibaum
Würde das dann nicht nur so aussehen?
Verzeichnis ├Datei ├Datei UnterVerzeichnis ├Datei ├Datei |
AW: Ordentlicher Dateibaum
Du musst zumindest noch Index und Level hinzufügen.
Besser du nimmmst gleich eine Art Treenode um die entsprechenden Childs und Parents zu verwalten, dann kannst du auch gleich den Data-Pointer mitverwenden um eventuelle Eigenschaften mitzuziehen. |
AW: Ordentlicher Dateibaum
Zitat:
|
AW: Ordentlicher Dateibaum
Zitat:
|
AW: Ordentlicher Dateibaum
Wie hä?
Hast dich schonmal mit Treenodes beschäftigt? Der Datapointer kann viele Probleme lösen wenn man mit dem Node weitere Informationen transportieren will. Hier mal ein Überblick was so alles interessant sein könnte, auch wenn der Code nicht perfekt ist, kannst vieleicht was davon gebrauchen.
Delphi-Quellcode:
const faNewAnyFileEx = FaAnyFile or $00000080;
Type PDatenTr=^TDatenTr; TDatenTr = record DTRDisplayName,DTROriginName,DTRMediaType, DTRSerial:WideString; DTRFolderList:TList; DTRAllSize:int64; end; PFileItem = ^TFileItem; TFileItem = record OriginName,DisplayName, TypeName,Path: WideString; Attributes:Integer; Size:int64; SizeS:String; Struct:TWin32FindData platform; FolderLevel,ImageIndex:Longint; end; PFolderItem = ^TFolderItem; TFolderItem = record OriginName,DisplayName, TypeName,Path: WideString; FileList:TList; Attributes: Integer; Size:int64; SizeS:String; Struct:TWin32FindData platform; FolderLevel,Index,Absoluteindex,ImageIndex:Longint; end; TGetDirsResult=Record FolderCnt,Filecnt:Longint; AllSize:int64; end; Var BreakScan,isClosing:Boolean; CurrentOut:WideString; FDT:PDatenTr; _Absoluteindex,_Foldercnt,_Filecnt:Longint; _AllSize:int64; Function ScanDrive(ADrv,ADirectory: Widestring; Var AFolderList:Tlist;Level_,Index_:Longint;FolderItem_:PFolderItem):TGetDirsResult; var SR: TSearchRec; NewNode: TTreeNode; Tmp2:String; L1:Longint; P:Longint; FileItem:PFileItem; FolderItem:PFolderItem; W:Widestring; begin while BreakScan or isClosing do exit; W:='\\'; P:=Pos(W,ADirectory); Delete(ADirectory,P,1); if FindFirst(ADrv+ADirectory+'*', faNewAnyFileEx, SR) = 0 then begin try repeat if ((SR.Name <> '.') and (SR.Name <> '..')) then begin if ((SR.Attr and faDirectory) <> 0) then begin inc(_Absoluteindex); FolderItem := New(PFolderItem); FolderItem.FileList:=TList.Create; with FolderItem^ do begin FolderLevel:=Level_; Index:=Index_; Absoluteindex:=_Absoluteindex; OriginName:=SR.Name; DisplayName:=OriginName; Struct:=SR.FindData; Path:=ADirectory; end; AFolderList.Insert(_Absoluteindex,FolderItem); inc(_FolderCnt); if isClosing or breakscan then begin FindClose(SR); exit; end; CurrentOut:=ADrv+ADirectory+SR.Name; Index_:=Index_+1; ScanDrive(ADrv,ADirectory+SR.Name+'\',AFolderList,Level_+1,0,FolderItem); end else begin FileItem := New(PFileItem); _AllSize:=_AllSize+SR.Size; FileItem.OriginName := SR.Name; FileItem.DisplayName:=FileItem.OriginName; FileItem.FolderLevel:=Level_-1; FileItem.Path:=ADirectory; FileItem.Struct:=SR.FindData; FolderItem_.FileList.Add(FileItem); inc(_Filecnt); if isClosing or breakscan then begin FindClose(SR); exit; end; CurrentOut:=ADrv+ADirectory+SR.Name; end; end; until FindNext(SR) <> 0; finally FindClose(SR); end; end; end; Function GetNextFolderLevel(Absoluteindex:Longint;FolderList:TList):TList; Var L1,L2,cnt2:Longint; BaseItem,NextItem:PFolderItem; BL:integer; begin Result:=TList.Create; try begin L1:=FolderList.Count; L2:=L1-1; while (Absoluteindex>L1-2) do Exit; BaseItem:=PFolderItem(FolderList[Absoluteindex]); BL:=BaseItem.FolderLevel+1; for cnt2 := Absoluteindex+1 to L2 - 1 do begin NextItem:=PFolderItem(FolderList[cnt2]); if (NextItem.FolderLevel=BL) then Result.Add(NextItem); if (NextItem.FolderLevel<BL) then Exit; end; end; Except Result.Free; end; end; Function GetPFoldersLeveled(Level:Longint;FolderList:TList):TList; Var L1,cnt1:Longint; Item:PFolderItem; begin while not Assigned(FolderList) do Exit; Result:=TList.Create; try begin cnt1:=0; while (cnt1<FolderList.Count) do begin Item:=PFolderItem(FolderList[cnt1]); if Assigned(Item) and (Item.FolderLevel=Level) then Result.Add(Item); cnt1:=cnt1+1; end; end; Except Result.Free; end; end; Procedure MaxLevel2(MaxLevel_:integer;Tree_:TTreeview;Src_:PFolderitem;NextList:TList; TargetNode_: TTreeNode;DTRFolderList:TList); var i: LongInt; Tmp:TTreenode; L1:Longint; NextItem:PFolderItem; begin tmp :=Tree_.Items.AddChild(TargetNode_,Src_.DisplayName); tmp.Data:=Src_; //Alle Daten des Ordners als Pointer(PFolderitem) anhängen ! L1:=NextList.Count; if (L1>0) then Tmp.HasChildren:=True; if (MaxLevel_>Src_.FolderLevel) then begin for i := 0 to L1-1 do begin NextItem:=PFolderItem(NextList[i]); MaxLevel2(MaxLevel_,Tree_,NextItem,GetNextFolderLevel(Nextitem.Absoluteindex,DTRFolderList) , Tmp,DTRFolderList); end; end; end; Procedure BuildTV(aTV:TTreeview;aDTR:PDatenTr); Var Folderitem:PFolderItem; L1,cnt1:Longint; BaseList,NextList:TList; AktNode_:TTreenode; begin if Assigned(aDTR) then with PDatenTr(aDTR)^ do begin BaseList:=GetPFoldersLeveled(0,DTRFolderList); Aktnode_:=aTV.items.AddChild(nil,'Datenträger:'); L1:=BaseList.Count; for cnt1:= 0 to L1-1 do begin Folderitem:=PFolderItem(BaseList[cnt1]); NextList:=GetNextFolderLevel(Folderitem.Absoluteindex,DTRFolderList); MaxLevel2(2,aTV,FolderItem,NextList,AktNode_,DTRFolderList); //Maximal 2. Level anzeigen wegen Performance end; BaseList.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); Var FolderItem:PFolderItem; begin FDT:=New(PDatenTr); FolderItem:=New(PFolderItem); Folderitem.FileList:=TList.Create; FDT.DTRFolderList:=TList.Create; FDT.DTRFolderList.Add(Folderitem); _Absoluteindex:=-1; ScanDrive('F:\','',FDT.DTRFolderList,0,0,Folderitem); end; procedure TForm1.Button2Click(Sender: TObject); begin BuildTV(Treeview1,FDT); end; procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin isClosing:=True; end; procedure TForm1.Timer1Timer(Sender: TObject); begin Timer1.Interval:=100; Label1.Caption:=CurrentOut; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:28 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz