Tworzę mały programik do łączenia się z ftp i przeszukiwania jego podkatalogów wzgledem podanej lokalizacji. Do ftp łącze się używając biblioteki wininet.
Pliki lub katalogi z jednej podanej lokalizacji, bez problemu mogę wylistować . Zaciąłem sie na tym, że nie moge dać rady z wylistowaniem podkatalogów i znajdujących się w nich plików. Korzystam z BCB 2009.
Prosiłbym o pomoc i podpowiedź jak zrobić rekurencyjne wywoływanie funkcji 'ListujFtp', tak aby można było listować pliki i podkatalogi względem podanej lokalizacji. Najprawdopodobniej obecna kontrukcja funkcji nie pozwala na rekurencyjne wywoływanie (problem z uchwytem 'hFile'), ale nie wiem jak to zrobić.
Poniżej przydstawiam kompletne, działające funkcje łączenia się i listowania plików/katalogów z podanej lokalizacji:
- Kod: Zaznacz cały
HINTERNET hFind, hOpen, hConnect; //globalnie - uchwyty
void __fastcall PolaczFtp(String Host, String Login, String Pass) //łaczenie z ftp
{
hOpen = InternetOpen(ParamStr(0).t_str(), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 );
if(hOpen==0)
{
ShowMessage("Brak możliwości otworzenia połączenia internetowego");
}
hConnect = InternetConnect(hOpen, Host.t_str(),21,Login.t_str(),Pass.t_str() ,INTERNET_SERVICE_FTP, 0, 0);
if(hConnect==0)
{
ShowMessage("Nie można połączyć z: "+Host);
}
else
{
ShowMessage("Połączony z: "+Host);
}
}
//----------------------------------------------------------------------------
void __fastcall ListujFtp(TListBox *Lista, String Dir) //listowanie plików/katalogów
{
WIN32_FIND_DATA w32fd;
if (hConnect!=0)
{
try
{
hFind = FtpFindFirstFile(hConnect,Dir.t_str(), &w32fd, INTERNET_FLAG_RELOAD, 0); //INTERNET_FLAG_RELOAD lub INTERNET_FLAG_NO_CACHE_WRITE, szczegóły na TechNet
if(hFind!=0)
{
try
{
do
{
if((w32fd.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY) & ((String)w32fd.cFileName!=".") & ((String)w32fd.cFileName!="..")) //obiekt jest katalogiem
{
Lista->Items->Add("[DIR]"+(String)w32fd.cFileName); //tutaj listuje katalogi
}
else if(w32fd.dwFileAttributes!=FILE_ATTRIBUTE_DIRECTORY)
{
Lista->Items->Add((String)w32fd.cFileName); //tutaj listuje pliki
}
//tutaj gdzie trzeba by było wstawic funcje rekurencyjnego wołania tej funkcji, ale miałem z tym problem
}
while(InternetFindNextFile(hFind, &w32fd));
}
__finally
{
InternetCloseHandle(hFind);
}
}
else
{
ShowMessage("Problem z uchwytem hFind!"); //TUTAJ JEST PROBLEM PRZY REKURENCYJNYM WOŁANIU FUNKCJI 'ListujFtp'
}
}
__finally
{ }
}
else
{
ShowMessage("Brak połączenia z: "+Host);
}
}
//----------------------------------------------------------------------------
void __fastcall RozlaczFtp(void) //rozłaczanie z Hostem
{
if(hConnect!=0) InternetCloseHandle(hConnect);
if(hOpen!=0) InternetCloseHandle(hOpen);
}
//----------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender) //zestawienie połączenia
{
PolaczFtp(Edit1->Text,Edit2->Text,Edit3->Text); //podaje dane do połączenia z ftp.
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender) //rozłączenie z ftp
{
RozlaczFtp();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender) //wywołanie funkcji listowania plików/katalogów na ftp
{
ListBox1->Clear();
ListujFtp(ListBox1,Edit4->Text); //tutaj podaje lokalizacje katalogu, który chce przeszukac
}
//---------------------------------------------------------------------------
Bedę wdzięczny za pomoc.