首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ Builder >

ftp遍历文件夹解决方法

2013-06-26 
ftp遍历文件夹请教一个使用Indy10控件 ftp遍历文件夹的问题。ftp是成功连接的,以下是主要代码。在头文件中定

ftp遍历文件夹
请教一个使用Indy10控件 ftp遍历文件夹的问题。
ftp是成功连接的,以下是主要代码。
在头文件中定义结构和list类型 如下:

AnsiString curname;            //本地文件名
         TList *dirString;
 struct TDirList
  {
char filename[200];     //文件名
char upfilename[200];   //上级文件名
int  dir;               //文件类型
int  num;               //遍历标志
  };
 typedef TDirList* MList;

 在formshow中加入如下代码:      
idftp2->Connect();
   dirString = new TList();
   dirString->Clear();
           this->SelectListDir(this->hostlist);

bool  TForm2::SelectListDir(AnsiString dir) //自定义函数
{
   try
{
  int i = 0;
  MList mylist;
  AnsiString filename = "";   //当前文件夹或文件名
  AnsiString len = "";
  AnsiString uplen = "";      //当前文件或文件夹的上级目录(完整路径)
  idftp2->ChangeDir(dir);
  idftp2->List();
  mylist = new TDirList;
  if( idftp2->DirectoryListing->Count == 0 )   //如果当前文件为空文件夹
   {
  StrECopy(mylist->filename,filename.c_str());
  len = (AnsiString)mylist->filename;
  mylist->filename[len.Length() + 1] = 0x0;        //给结构元素赋值
  StrECopy(mylist->upfilename,dir.c_str());
  uplen = (AnsiString)mylist->upfilename;
  mylist->upfilename[uplen.Length() + 1] = 0x0;    //给结构元素赋值
  mylist->dir = -1;                      //-1表示该文件夹为空
  mylist->num = 1;
  dirString->Add(mylist);         //加入队列
  return true;
   }
  else
   {
      if(dir == this->hostlist)       //curname用于记录当前文件的绝对路径
{
   curname = dir ;
}
  else
{
   curname += "\" + dir;
}

  while( i <= idftp2->DirectoryListing->Count)   
{
   filename = AnsiToUtf8(idftp2->DirectoryListing->Items[i]->FileName);
   StrECopy(mylist->filename,filename.c_str());
   len = (AnsiString)mylist->filename;
   mylist->filename[len.Length() + 1] = 0x0;
   StrECopy(mylist->upfilename,curname.c_str());
   uplen = (AnsiString)mylist->upfilename;
   mylist->upfilename[uplen.Length() + 1] = 0x0;
   mylist->num = 1;                  //给结构元素赋值


   if(idftp2->DirectoryListing->Items[i]->ItemType == ditFile)
 {
                                        mylist->dir = 1;   //表示为文件
dirString->Add(mylist);  //加入队列
continue;
 }
   else
 {
                                        mylist->dir = 0;   //表示为文件夹
dirString->Add(mylist); //加入队列
SelectListDir(filename.c_str());  //如果是文件夹,进入递归
 }
   i++;
}
  return true;
   }
}
   catch(Exception &e)
{
  s = "函数SelectListDir(AnsiString dir)错误,遍历文件夹时失败,请检查!!\n" + e.Message;;
  ts = "提示:";
  Application->MessageBoxA(s.c_bstr(),ts.c_bstr(),MB_OK+16);
}
}



程序没有报错,但只是单一的走一个文件夹,如果目录中存在多个文件夹时,还是只进入一个文件夹;
进入调试状态看了看,好像没有递归成功,当程序运行到最低层文件夹后返回时,变量就无法再获取到值了,然后就直接运行完了;
请指点一下代码的错误;
再有就是在bcb中如果让函数返回一个结构呢,
如上面的结构为例:
在头文件中这样写 MList a();
定义函数时这样写 MList TForm2::a() {}
然后就报定义错误的提示,写成MList* a(); 和  MList* TForm2::a() {}也不行,请问应该如果定义呢?
[解决办法]
1 因为while(?i?<=?idftp2->DirectoryListing->Count)???
进入递归的时候idftp2->DirectoryListing->Count 会被改变 但是你外层还拿它当while的条件。

2 返回一个指针就可以了。
  MList * a() {
    ...
  }
[解决办法]
1 进入一次递归就创建一个idftp 或者每次ChangeDir之前把需要的访问的idftp的数据给保存下来 不再依赖idftp2这个指针来取后续的数据。

2 返回的指针需要是函数体外有效的指针。

热点排行