var
FileList: TStringList;
i: integer;
FtpItems: TIdFTPListItems;
begin
try
if not ftp.Connected then exit;
FileList := TStringList.Create;
try
ftp.List(FileList);
FtpItems := TIdFTPListItems.Create;
FtpItems := ftp.DirectoryListing;
for i := 0 to FtpItems.Count - 1 do
begin
if FtpItems.Items[i].FileName[1] <> '.' then
if FtpItems.Items[i].ItemType = ditDirectory then
begin
ShowMessage(FtpItems.Items[i].FileName);
ftp.ChangeDir(FtpItems.Items[i].FileName);
showmessage('before当前目录:' + ftp.RetrieveCurrentDir);
SynchronizationServerToClient;
showmessage('after当前目录:' + ftp.RetrieveCurrentDir);
//ftp.ChangeDir('..');
ftp.ChangeDirUp;
end
else
begin
ShowMessage(FtpItems.Items[i].FileName);
end;
end;
finally
FileList.Free;
end;
except
showmessage('Error当前目录:' + ftp.RetrieveCurrentDir);
end;
end;
递归进入子目录的时候正常,但是递归退到根目录的时候老报下面错误,大家帮忙分析分析!
Project Project1.exe raised exception class EListError with message 'List index out of bounds (3)'. Process stopped. Use Step or Run to continue.
我自己认为是IDFTP组件的List和DirectoryListing返回的值不相同,但是找不到解决办法,不知道是否跟FTP服务器有关系,我的是Serv-U 5.0 Beta.
17 个解决方案
#1
或者那位兄弟计算机上安装有FTP,用上面的代码帮我测试测试也行...
#2
呵呵
Serv-U等服务器支持List -a参数的,不需要使用递归这么低效率的方法,一次就可以获得全部列表的
LYFTP就全面支持List -A或递归搜索获取服务器的目录信息
http://lysoft.7u7.net
Serv-U等服务器支持List -a参数的,不需要使用递归这么低效率的方法,一次就可以获得全部列表的
LYFTP就全面支持List -A或递归搜索获取服务器的目录信息
http://lysoft.7u7.net
#3
支持么? 我试验了一下,好像不支持list -a?
#4
当然支持的,连IIS的FTP都可以!
Indy本来是不支持的,你需要修改IdFTP.pas的代码,呵呵
http://lysoft.7u7.net
Indy本来是不支持的,你需要修改IdFTP.pas的代码,呵呵
http://lysoft.7u7.net
#5
老兄,你说的List -a是通过什么方式执行的?麻烦说的详细点,我的大脑已经被搞晕了。
我在命令行执行ls -a返回的还是本目录下的文件和目录,没有列出子目录中的文件和子目录。
我在命令行执行ls -a返回的还是本目录下的文件和目录,没有列出子目录中的文件和子目录。
#6
我试验了一下上面的程序
有同样的问题,我觉得是不是因为每一次递归都要
create几个东西造成的,于是将递归放在一个过程中
这样似乎好了,但是有其他问题。
有同样的问题,我觉得是不是因为每一次递归都要
create几个东西造成的,于是将递归放在一个过程中
这样似乎好了,但是有其他问题。
#7
不是吧,
难道Serv-U服务器支持,而Indy客户端不支持?
那还是搞不成啊!
难道Serv-U服务器支持,而Indy客户端不支持?
那还是搞不成啊!
#8
TO: zoologist(王朝)
我觉得是不是因为每一次递归都要create几个东西造成的.
你说的Create几个东西是指?不太明白,也许我没有想到。
我觉得是不是因为每一次递归都要create几个东西造成的.
你说的Create几个东西是指?不太明白,也许我没有想到。
#9
up
#10
搞错那么点,应该是List -R才是
自己下载LYFTP来研究了
再具体细节不便公开的
http://lysoft.7u7.net
自己下载LYFTP来研究了
再具体细节不便公开的
http://lysoft.7u7.net
#11
list -r 也不好用啊?
我的意思是
FileList := TStringList.Create;
FtpItems := TIdFTPListItems.Create;
这样的,并且每一次create后又没有destroy不知道会不会影响。
我的意思是
FileList := TStringList.Create;
FtpItems := TIdFTPListItems.Create;
这样的,并且每一次create后又没有destroy不知道会不会影响。
#12
递归是不能Destroy的,因为进入递归的时候把创建对象压入堆栈了。如果释放了的话,后面就会报错的。
搞定: ftp.List(str,'-R', true); 可以列出全部的文件和子目录。
谢谢 ly_liuyang(Liu Yang)。
搞定: ftp.List(str,'-R', true); 可以列出全部的文件和子目录。
谢谢 ly_liuyang(Liu Yang)。
#13
最好能够用递归的方法实现,兄弟们帮帮忙了。
因为List -R 得到的列表信息乱得很,不只包含目录名和文件名,还有其它的东西。
因为List -R 得到的列表信息乱得很,不只包含目录名和文件名,还有其它的东西。
#14
procedure TFMain.Button1Click(Sender: TObject);
var
FileList: TStringList;
FtpItems: TIdFTPListItems;
procedure getOne;
var
i: integer;
begin
ftpClient.List(FileList);
FtpItems := ftpClient.DirectoryListing;
for i := 0 to FtpItems.Count - 1 do
begin
if FtpItems.Items[i].FileName[1] <> '.' then
if FtpItems.Items[i].ItemType = ditDirectory then
begin
ShowMessage(FtpItems.Items[i].FileName);
ftpClient.ChangeDir(FtpItems.Items[i].FileName);
showmessage('before当前目录:' + ftpClient.RetrieveCurrentDir);
GetOne;
showmessage('after当前目录:' + ftpClient.RetrieveCurrentDir);
ftpClient.ChangeDirUp;
end
else
begin
ShowMessage(FtpItems.Items[i].FileName);
end;
end;
end;
begin
try
if not ftpClient.Connected then exit;
FileList := TStringList.Create;
try
ftpClient.List(FileList);
FtpItems := TIdFTPListItems.Create;
FtpItems := ftpClient.DirectoryListing;
getOne;
finally
FileList.Free;
end;
except
showmessage('Error当前目录:' + ftpClient.RetrieveCurrentDir);
end;
end;
var
FileList: TStringList;
FtpItems: TIdFTPListItems;
procedure getOne;
var
i: integer;
begin
ftpClient.List(FileList);
FtpItems := ftpClient.DirectoryListing;
for i := 0 to FtpItems.Count - 1 do
begin
if FtpItems.Items[i].FileName[1] <> '.' then
if FtpItems.Items[i].ItemType = ditDirectory then
begin
ShowMessage(FtpItems.Items[i].FileName);
ftpClient.ChangeDir(FtpItems.Items[i].FileName);
showmessage('before当前目录:' + ftpClient.RetrieveCurrentDir);
GetOne;
showmessage('after当前目录:' + ftpClient.RetrieveCurrentDir);
ftpClient.ChangeDirUp;
end
else
begin
ShowMessage(FtpItems.Items[i].FileName);
end;
end;
end;
begin
try
if not ftpClient.Connected then exit;
FileList := TStringList.Create;
try
ftpClient.List(FileList);
FtpItems := TIdFTPListItems.Create;
FtpItems := ftpClient.DirectoryListing;
getOne;
finally
FileList.Free;
end;
except
showmessage('Error当前目录:' + ftpClient.RetrieveCurrentDir);
end;
end;
#15
TO: zoologist(王朝)
你的算法在你那边可以成功吗?我这儿还是报:Project Project1.exe raised exception class EListError with message 'List index out of bounds (3)'. Process stopped. Use Step or Run to continue.
你的算法在你那边可以成功吗?我这儿还是报:Project Project1.exe raised exception class EListError with message 'List index out of bounds (3)'. Process stopped. Use Step or Run to continue.
#16
贴一个console 可运行
program listall;
{$APPTYPE CONSOLE}
uses
SysUtils,
IdBaseComponent,
IdComponent,
IdTCPConnection,
IdTCPClient,
IdFTP,
IdFTPList,
Classes;
var
FTP:TIdFTP;
procedure ListThem(CurrentDir:String);
var
LS:TIdFTPListItems;
FileCount:Integer;
tempLst:TStringList;
begin
FTP.ChangeDir(CurrentDir);
tempLst:=TStringList.Create;
FTP.List(tempLst);
LS:=TIdFTPListItems.Create;
LS.Assign(FTP.DirectoryListing);
for FileCount:=0 to LS.Count-1 do
begin
if LS.Items[FileCount].ItemType = ditDirectory then
begin
if (LS.Items[FileCount].FileName<>'.')
and (LS.Items[FileCount].FileName<>'..')
then
begin
writeln('Entering...'+LS.Items[FileCount].FileName);
ListThem(CurrentDir+'/'+LS.Items[FileCount].FileName);
end;
end
else
begin
if LS.Items[FileCount].FileName='logo.jpg' then
write('err!');
writeln('File:',LS.Items[FileCount].FileName);
end;
end;
if CurrentDir<>'/' then
begin
FTP.ChangeDirUp;
CurrentDir:=FTP.RetrieveCurrentDir;
end;
end;
begin
FTp:=TidFTP.Create(nil);
FTP.Username:='anonymous';
FTP.Password:='asdasd';
FTP.Host:='172.18.18.85';
FTP.Port:=21;
FTP.Connect;
writeln(FTP.LoginMsg.GenerateReply);
ListThem('/');
FTP.Disconnect;
readln;
end.
program listall;
{$APPTYPE CONSOLE}
uses
SysUtils,
IdBaseComponent,
IdComponent,
IdTCPConnection,
IdTCPClient,
IdFTP,
IdFTPList,
Classes;
var
FTP:TIdFTP;
procedure ListThem(CurrentDir:String);
var
LS:TIdFTPListItems;
FileCount:Integer;
tempLst:TStringList;
begin
FTP.ChangeDir(CurrentDir);
tempLst:=TStringList.Create;
FTP.List(tempLst);
LS:=TIdFTPListItems.Create;
LS.Assign(FTP.DirectoryListing);
for FileCount:=0 to LS.Count-1 do
begin
if LS.Items[FileCount].ItemType = ditDirectory then
begin
if (LS.Items[FileCount].FileName<>'.')
and (LS.Items[FileCount].FileName<>'..')
then
begin
writeln('Entering...'+LS.Items[FileCount].FileName);
ListThem(CurrentDir+'/'+LS.Items[FileCount].FileName);
end;
end
else
begin
if LS.Items[FileCount].FileName='logo.jpg' then
write('err!');
writeln('File:',LS.Items[FileCount].FileName);
end;
end;
if CurrentDir<>'/' then
begin
FTP.ChangeDirUp;
CurrentDir:=FTP.RetrieveCurrentDir;
end;
end;
begin
FTp:=TidFTP.Create(nil);
FTP.Username:='anonymous';
FTP.Password:='asdasd';
FTP.Host:='172.18.18.85';
FTP.Port:=21;
FTP.Connect;
writeln(FTP.LoginMsg.GenerateReply);
ListThem('/');
FTP.Disconnect;
readln;
end.
#17
我搞定了,就是通过分析List -a返回的内容解决的,虽然很烦,但是总算个解决方案了。
#1
或者那位兄弟计算机上安装有FTP,用上面的代码帮我测试测试也行...
#2
呵呵
Serv-U等服务器支持List -a参数的,不需要使用递归这么低效率的方法,一次就可以获得全部列表的
LYFTP就全面支持List -A或递归搜索获取服务器的目录信息
http://lysoft.7u7.net
Serv-U等服务器支持List -a参数的,不需要使用递归这么低效率的方法,一次就可以获得全部列表的
LYFTP就全面支持List -A或递归搜索获取服务器的目录信息
http://lysoft.7u7.net
#3
支持么? 我试验了一下,好像不支持list -a?
#4
当然支持的,连IIS的FTP都可以!
Indy本来是不支持的,你需要修改IdFTP.pas的代码,呵呵
http://lysoft.7u7.net
Indy本来是不支持的,你需要修改IdFTP.pas的代码,呵呵
http://lysoft.7u7.net
#5
老兄,你说的List -a是通过什么方式执行的?麻烦说的详细点,我的大脑已经被搞晕了。
我在命令行执行ls -a返回的还是本目录下的文件和目录,没有列出子目录中的文件和子目录。
我在命令行执行ls -a返回的还是本目录下的文件和目录,没有列出子目录中的文件和子目录。
#6
我试验了一下上面的程序
有同样的问题,我觉得是不是因为每一次递归都要
create几个东西造成的,于是将递归放在一个过程中
这样似乎好了,但是有其他问题。
有同样的问题,我觉得是不是因为每一次递归都要
create几个东西造成的,于是将递归放在一个过程中
这样似乎好了,但是有其他问题。
#7
不是吧,
难道Serv-U服务器支持,而Indy客户端不支持?
那还是搞不成啊!
难道Serv-U服务器支持,而Indy客户端不支持?
那还是搞不成啊!
#8
TO: zoologist(王朝)
我觉得是不是因为每一次递归都要create几个东西造成的.
你说的Create几个东西是指?不太明白,也许我没有想到。
我觉得是不是因为每一次递归都要create几个东西造成的.
你说的Create几个东西是指?不太明白,也许我没有想到。
#9
up
#10
搞错那么点,应该是List -R才是
自己下载LYFTP来研究了
再具体细节不便公开的
http://lysoft.7u7.net
自己下载LYFTP来研究了
再具体细节不便公开的
http://lysoft.7u7.net
#11
list -r 也不好用啊?
我的意思是
FileList := TStringList.Create;
FtpItems := TIdFTPListItems.Create;
这样的,并且每一次create后又没有destroy不知道会不会影响。
我的意思是
FileList := TStringList.Create;
FtpItems := TIdFTPListItems.Create;
这样的,并且每一次create后又没有destroy不知道会不会影响。
#12
递归是不能Destroy的,因为进入递归的时候把创建对象压入堆栈了。如果释放了的话,后面就会报错的。
搞定: ftp.List(str,'-R', true); 可以列出全部的文件和子目录。
谢谢 ly_liuyang(Liu Yang)。
搞定: ftp.List(str,'-R', true); 可以列出全部的文件和子目录。
谢谢 ly_liuyang(Liu Yang)。
#13
最好能够用递归的方法实现,兄弟们帮帮忙了。
因为List -R 得到的列表信息乱得很,不只包含目录名和文件名,还有其它的东西。
因为List -R 得到的列表信息乱得很,不只包含目录名和文件名,还有其它的东西。
#14
procedure TFMain.Button1Click(Sender: TObject);
var
FileList: TStringList;
FtpItems: TIdFTPListItems;
procedure getOne;
var
i: integer;
begin
ftpClient.List(FileList);
FtpItems := ftpClient.DirectoryListing;
for i := 0 to FtpItems.Count - 1 do
begin
if FtpItems.Items[i].FileName[1] <> '.' then
if FtpItems.Items[i].ItemType = ditDirectory then
begin
ShowMessage(FtpItems.Items[i].FileName);
ftpClient.ChangeDir(FtpItems.Items[i].FileName);
showmessage('before当前目录:' + ftpClient.RetrieveCurrentDir);
GetOne;
showmessage('after当前目录:' + ftpClient.RetrieveCurrentDir);
ftpClient.ChangeDirUp;
end
else
begin
ShowMessage(FtpItems.Items[i].FileName);
end;
end;
end;
begin
try
if not ftpClient.Connected then exit;
FileList := TStringList.Create;
try
ftpClient.List(FileList);
FtpItems := TIdFTPListItems.Create;
FtpItems := ftpClient.DirectoryListing;
getOne;
finally
FileList.Free;
end;
except
showmessage('Error当前目录:' + ftpClient.RetrieveCurrentDir);
end;
end;
var
FileList: TStringList;
FtpItems: TIdFTPListItems;
procedure getOne;
var
i: integer;
begin
ftpClient.List(FileList);
FtpItems := ftpClient.DirectoryListing;
for i := 0 to FtpItems.Count - 1 do
begin
if FtpItems.Items[i].FileName[1] <> '.' then
if FtpItems.Items[i].ItemType = ditDirectory then
begin
ShowMessage(FtpItems.Items[i].FileName);
ftpClient.ChangeDir(FtpItems.Items[i].FileName);
showmessage('before当前目录:' + ftpClient.RetrieveCurrentDir);
GetOne;
showmessage('after当前目录:' + ftpClient.RetrieveCurrentDir);
ftpClient.ChangeDirUp;
end
else
begin
ShowMessage(FtpItems.Items[i].FileName);
end;
end;
end;
begin
try
if not ftpClient.Connected then exit;
FileList := TStringList.Create;
try
ftpClient.List(FileList);
FtpItems := TIdFTPListItems.Create;
FtpItems := ftpClient.DirectoryListing;
getOne;
finally
FileList.Free;
end;
except
showmessage('Error当前目录:' + ftpClient.RetrieveCurrentDir);
end;
end;
#15
TO: zoologist(王朝)
你的算法在你那边可以成功吗?我这儿还是报:Project Project1.exe raised exception class EListError with message 'List index out of bounds (3)'. Process stopped. Use Step or Run to continue.
你的算法在你那边可以成功吗?我这儿还是报:Project Project1.exe raised exception class EListError with message 'List index out of bounds (3)'. Process stopped. Use Step or Run to continue.
#16
贴一个console 可运行
program listall;
{$APPTYPE CONSOLE}
uses
SysUtils,
IdBaseComponent,
IdComponent,
IdTCPConnection,
IdTCPClient,
IdFTP,
IdFTPList,
Classes;
var
FTP:TIdFTP;
procedure ListThem(CurrentDir:String);
var
LS:TIdFTPListItems;
FileCount:Integer;
tempLst:TStringList;
begin
FTP.ChangeDir(CurrentDir);
tempLst:=TStringList.Create;
FTP.List(tempLst);
LS:=TIdFTPListItems.Create;
LS.Assign(FTP.DirectoryListing);
for FileCount:=0 to LS.Count-1 do
begin
if LS.Items[FileCount].ItemType = ditDirectory then
begin
if (LS.Items[FileCount].FileName<>'.')
and (LS.Items[FileCount].FileName<>'..')
then
begin
writeln('Entering...'+LS.Items[FileCount].FileName);
ListThem(CurrentDir+'/'+LS.Items[FileCount].FileName);
end;
end
else
begin
if LS.Items[FileCount].FileName='logo.jpg' then
write('err!');
writeln('File:',LS.Items[FileCount].FileName);
end;
end;
if CurrentDir<>'/' then
begin
FTP.ChangeDirUp;
CurrentDir:=FTP.RetrieveCurrentDir;
end;
end;
begin
FTp:=TidFTP.Create(nil);
FTP.Username:='anonymous';
FTP.Password:='asdasd';
FTP.Host:='172.18.18.85';
FTP.Port:=21;
FTP.Connect;
writeln(FTP.LoginMsg.GenerateReply);
ListThem('/');
FTP.Disconnect;
readln;
end.
program listall;
{$APPTYPE CONSOLE}
uses
SysUtils,
IdBaseComponent,
IdComponent,
IdTCPConnection,
IdTCPClient,
IdFTP,
IdFTPList,
Classes;
var
FTP:TIdFTP;
procedure ListThem(CurrentDir:String);
var
LS:TIdFTPListItems;
FileCount:Integer;
tempLst:TStringList;
begin
FTP.ChangeDir(CurrentDir);
tempLst:=TStringList.Create;
FTP.List(tempLst);
LS:=TIdFTPListItems.Create;
LS.Assign(FTP.DirectoryListing);
for FileCount:=0 to LS.Count-1 do
begin
if LS.Items[FileCount].ItemType = ditDirectory then
begin
if (LS.Items[FileCount].FileName<>'.')
and (LS.Items[FileCount].FileName<>'..')
then
begin
writeln('Entering...'+LS.Items[FileCount].FileName);
ListThem(CurrentDir+'/'+LS.Items[FileCount].FileName);
end;
end
else
begin
if LS.Items[FileCount].FileName='logo.jpg' then
write('err!');
writeln('File:',LS.Items[FileCount].FileName);
end;
end;
if CurrentDir<>'/' then
begin
FTP.ChangeDirUp;
CurrentDir:=FTP.RetrieveCurrentDir;
end;
end;
begin
FTp:=TidFTP.Create(nil);
FTP.Username:='anonymous';
FTP.Password:='asdasd';
FTP.Host:='172.18.18.85';
FTP.Port:=21;
FTP.Connect;
writeln(FTP.LoginMsg.GenerateReply);
ListThem('/');
FTP.Disconnect;
readln;
end.
#17
我搞定了,就是通过分析List -a返回的内容解决的,虽然很烦,但是总算个解决方案了。