求助:递归越界——关于FTP目录传输(100分)

  • 主题发起人 主题发起人 火柴天堂
  • 开始时间 开始时间

火柴天堂

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure downloaddir(directorylistbox1:tdirectorylistbox;nmftp1:tnmftp;Fil
elistbox4,Filelistbox2:tFilelistbox;dirname:string);
var
hei,i:integer;
localdir:string;
remotedir:string;
begin
mkdir(dirname); //在本地创建相同的目录
localdir:=DirectoryListBox1.directory+'/'+dirname;
//读取本地的当前目录
directorylistbox1.directory:=localdir;
remotedir:=nmftp1.currentdir+'/'+dirname;
//读取远地的当前目录
nmftp1.changedir(remotedir); //远地进入下一层目录
if Filelistbox4.items.count>0 then //下载该目录下的文件
for hei:=0 to (Filelistbox4.items.count-1) do
nmftp1.download(remotedir+'/'+Filelistbox4.items.strings[hei],localdir+'/'+Filelistbox4.items.strings[hei]);
if Filelistbox2.items.count>1 then //mulu
for i:=1 to (Filelistbox2.items.count-1) do
begin
//showmessage(Filelistbox2.items.strings[hei]);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//总是在这儿越界,不知为什么.
try
downloaddir (directorylistbox1,nmftp1,Filelistbox4,
Filelistbox2,Filelistbox2.items.strings);
except
on E:exception do
continue;
end;
end;
end;

递归到最底层向上返回时,报错out of bound(*)
请各位大虾指教
若有可能请给出正确的方法(具体程序),告急!!!
 
这些其实就是调试方法的问题。
首先试着不要与FTP挂勾,使用其他数据源测试你的递归。如果没问题。
那就是说明FTP造成的,而不是递归造成。
比如,如果NMFTP控件创建了它自己的线程。它会即时返回当前的结果,
而在你的循环中,可能Filelistbox2.items.count会发生变化。
没仔细看你的代码,SORRY。
 
showmessage(Filelistbox2.items.strings[hei]);
这一句不对应呀,???
 
是下面的递归出错,我知道是i返回的值产生了越界
但如何修改呢.如果用出栈,压栈来做,如何遍历目录
树,如何存储目录结构?请指教!毕业设计告急!!!
 
由于没有用过 nmftp, 所以只好凑合了。
用深度优先。
下面是伪代码。
procedure Get(aDirectory: string);
begin
repeat
得到一个文件(目录)s;
if s是目录 then
get(s)
else
下载;
until 这个目录的内容都已经访问
end;
 
我记得好象以前讨论过此问题,其算法如下:
(1)用一个动态数组来保存ftp目录;定义一个游标来访问动态数组;
(2)其实状态,设置需要下载的根目录保存到数组,游标初始值为0;
(3)通过游标得到目录名,通过FtpFind方法来获得此目录下的所有文件和目录,如
果是文件下载,否则保存目录名到数组中;
(4)游标下移,如果游标小于或等于数组的长度,执行(2);否则,下载完毕;
 
到头来还是自己搞定了
 
procedure downloaddir(directorylistbox1:tdirectorylistbox;nmftp1:tnmftp;Filelistbox4,Filelistbox2:tFilelistbox;dirname:string);
var T,S:array [1..100] of string;
Q,P,temp:string;
top,i:integer;
begin
top:=1;
T[1]:=DirectoryListBox1.Directory+'/'+dirname;
S[1]:=NMFTP1.CurrentDir+'/'+dirname;
mkdir(DirectoryListBox1.Directory+'/'+dirname);
while top<>0 do
begin
p:=s[top]; //远地
q:=t[top]; //本地
NMFTP1.ChangeDir(p);
//mkdir(q);
chdir(q);
temp:=q;
top:=top-1;
if FileLIstBox4.Items.Count<>0 then
for i:=0 to FileListBox4.Items.Count-1 do
nmftp1.download(p+'/'+Filelistbox4.items.strings,q+
'/'+Filelistbox4.items.strings);
if FileLIstBox2.Items.Count>1 then
for i:=1 to FileListBox2.Items.Count-1 do
begin
top:=top+1;
s[top]:=NMFTP1.CurrentDir+'/'+FileListBox2.Items.Strings;
mkdir(FileListBox2.Items.Strings);
t[top]:=temp+'/'+FileListBox2.Items.Strings;
end;
end;
showmessage('目录下载完毕!');
 
用递归也可以

procedure DownLoadDirectory(Dir:string;FtpSvr: TNMFTP): integer;
var
AttList : TStrings;
NameList : TStrings;
count : integer;
i : integer;
Att : string;
begin
AttList := TStringList.Create;
NameList:= TStringList.Create;
FtpSvr.List;
AttList.Assign( FtpSvr.FTPDirectoryList.Attribute );
NameList.Assign(FtpSvr.FTPDirectoryList.name );
count := AttList.Count;
Chdir(dir);
if count = 0 then exit;

for i:=0 to count-1 do
begin
Att := AttList.Strings;
if( Att[1] = '-' ) then
begin
try
FtpSvr.Download( nameList.Stringsi],dir+ '/'+NameList.Strings );
except end;
end;
if( Att[1] = 'd' ) then
begin
mkdir(NameList.strings);
try
FtpSvr.ChangeDir(NameList.strings);
except end;
DownLoadDirectory( dir+'/'+NameList.Strings, FtpSvr );
chdir(dir);
try
FtpSvr.ChangeDir('..');
except end;
end;
end;
end;
 
多人接受答案了。
 
后退
顶部