方案
我试图复制标准的方法,从文件夹结构中的目录/文件夹填充树视图,从根目录开始,但使用IdFTP从远程服务器而不是我的本地硬盘驱动器获得结构。我希望结果看起来类似于Filezilla这样的客户端。
我使用了来自瑞士 Delphi 中心的this标准代码(用于显示我的硬盘结构),然后将其修改为使用IdFTP.ChangeDir(Directory)和IdFTP.List,而不是FindFirst()和FindNext()。
问题
我似乎已经得到了自己在一个混乱,因为它是不正确的'展开'递归,这样,一旦它遍历了远程服务器上的/cpanel/cashes/config目录,它不返回和遍历所有其他目录挂在根目录,但退出过程没有显示任何其他内容。此外,它似乎没有显示所有的顶级文件夹,但这可能只是由于顺序IdFTP. List返回它们的格式为
谁能告诉我我做错了什么?
如果您还能告诉我应该如何显示根(/),那将非常有帮助
(我已经注解掉了显示非目录,因为我在这个阶段只想要文件夹)
我期望看到的内容复制自Filezilla
我所看到的在 Delphi 中使用Ttreeview
我的代码
procedure TForm2.Button1Click(Sender: TObject);
var StartingDir : string;
begin
TreeView1.Items.BeginUpdate;
try
StartingDir := '/';
Screen.Cursor := crHourGlass;
TreeView1.Items.Clear;
FTPconnect; //procedure to connect to remote server
GetDirectories(TreeView1, StartingDir, nil, True);
FTPDisconnect; //procedure to disconnect from remote server
finally
TreeView1.Items.EndUpdate;
Screen.Cursor := crDefault;
end;
end;
procedure TForm2.GetDirectories(Tree: TTreeView; Directory: string; Item: TTreeNode; IncludeFiles: Boolean);
var
ItemTemp: TTreeNode;
DirItemType : TIdDirItemType ;
Filename , NewStartingDirectory: string;
i : Integer;
begin
Tree.Items.BeginUpdate;
IdFTP.ChangeDir(Directory);
IdFTP.List; //get directory of remote folder
i:=0;
repeat
DirItemType := IdFTP.DirectoryListing[I].ItemType;
Filename := IdFTP.DirectoryListing[I].FileName;
If (DirItemType = ditDirectory) and (Filename <> '.') and (Filename <> '..')then
begin
if DirItemType = ditDirectory then
Item := Tree.Items.AddChild(Item, Filename);
ItemTemp := Item.Parent;
if Directory = '/' then
NewStartingDirectory := Directory + Filename
else
NewStartingDirectory := Directory + '/' +Filename;
GetDirectories(Tree, NewStartingDirectory, Item, IncludeFiles);
Item := ItemTemp;
end
else
if IncludeFiles then
begin //this bit commented out as we only want to see directories
// if (Filename <> '.') and (Filename <> '..') then
// Tree.Items.AddChild(Item, Filename);
end;
inc(i);
until i = IdFTP.DirectoryListing.Count;
Tree.Items.EndUpdate;
end;
瑞士Delhpi中心代码(用于比较)
procedure TForm1.Button1Click(Sender: TObject);
var
Node: TTreeNode;
Path: string;
Dir: string;
begin
Dir := 'c:\temp';
Screen.Cursor := crHourGlass;
TreeView1.Items.BeginUpdate;
try
TreeView1.Items.Clear;
GetDirectories(TreeView1, Dir, nil, True);
finally
Screen.Cursor := crDefault;
TreeView1.Items.EndUpdate;
end;
end;
procedure TForm1.GetDirectories(Tree: TTreeView; Directory: string; Item: TTreeNode; IncludeFiles: Boolean);
var
SearchRec: TSearchRec;
ItemTemp: TTreeNode;
begin
Tree.Items.BeginUpdate;
if Directory[Length(Directory)] <> '\' then Directory := Directory + '\';
if FindFirst(Directory + '*.*', faDirectory, SearchRec) = 0 then
begin
repeat
if (SearchRec.Attr and faDirectory = faDirectory) and (SearchRec.Name[1] <> '.') then
begin
if (SearchRec.Attr and faDirectory > 0) then
Item := Tree.Items.AddChild(Item, SearchRec.Name);
ItemTemp := Item.Parent;
GetDirectories(Tree, Directory + SearchRec.Name, Item, IncludeFiles);
Item := ItemTemp;
end
else if IncludeFiles then
if SearchRec.Name[1] <> '.' then
Tree.Items.AddChild(Item, SearchRec.Name);
until FindNext(SearchRec) <> 0;
FindClose(SearchRec);
end;
Tree.Items.EndUpdate;
end;
我已经看过SO here-太复杂和错误的语言和here-类似于瑞士 Delphi 中心和here-错误的语言,不知道它在做什么。
如果使用TlistView更好,您能给我看一下使用它的等效代码吗?
1条答案
按热度按时间ig9co6j11#
未测试:
TIdFTP
变量设置为参数,因为TTreeView
也是一个参数,并且应该保持一致,而不是过时。for
循环而不是repeat until
。IncludeFiles
时将其删除。1.基本逻辑是如我在注解中所写的:
1.将所有文件夹字符串存储到您自己的列表中,并避免此时出现递归。
1.修复要连接一次的路径,而不是循环的每次迭代。
1.遍历该列表进行递归--此时
FTP
的状态无关紧要,您不会在不同级别上弄乱列表。1.当然,释放所创建的StringList示例。
未测试,但应编译。