CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Problem z funkcją TIdFTP

Problem z funkcją TIdFTP

problemy z tworzeniem programów do obsługi sieci, internetu, e-mail itp..

Problem z funkcją TIdFTP

Nowy postprzez Gepcio » sobota, 6 października 2012, 10:51

Za dużo nie będę się rozpisywał. Mam problem i już pokazuję jaki.
Kodzik:
KOD cpp:     UKRYJ  
void __fastcall TForm1::DownloadFolder(TIdFTP AFTP, UnicodeString ARemotePath, UnicodeString ALocalPath)
{
AFTP.ChangeDir("/");
AFTP.List();
for(int i=0;i<AFTP.DirectoryListing->Count;i++)
                {
                        if(AFTP.DirectoryListing->Items[i]->ItemType == ditFile)
                        {
                                AFTP.Get(ARemotePath + AFTP.DirectoryListing->Items[i]->FileName, ALocalPath + AFTP.DirectoryListing->Items[i]->FileName);
                        }
                }

                for(int i=0;i<AFTP.DirectoryListing->Count;i++)
                {
                        if(AFTP.DirectoryListing->Items[i]->ItemType == ditDirectory)
                        {
                          DownloadFolder(AFTP, ARemotePath + AFTP.DirectoryListing->Items[i]->FileName, ALocalPath + AFTP.DirectoryListing->Items[i]->FileName);
                          AFTP.ChangeDir(ARemotePath);
                        }
                }
}

I wyskakujący błąd:
Kod: Zaznacz cały
[bcc32 Error] MainForm.cpp(35): E2459 Delphi style classes must be constructed using operator new

przy linijce:
KOD cpp:     UKRYJ  
DownloadFolder(AFTP, ARemotePath + AFTP.DirectoryListing->Items[i]->FileName, ALocalPath + AFTP.DirectoryListing->Items[i]->FileName);


No i co tu jest źle? Powinno skompilować... Jak mam zapisać FUNKCJĘ jako KLASĘ? To niemożliwe.
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Chrome

Re: Problem z funkcją TIdFTP

Nowy postprzez Cyfrowy Baron » sobota, 6 października 2012, 11:05

Ja też nie będę się rozpisywał i wyjaśniał. Poprawny kod:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:
        void __fastcall DownloadFolder(TIdFTP *AFTP, UnicodeString ARemotePath, UnicodeString ALocalPath);


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
void __fastcall TForm1::DownloadFolder(TIdFTP *AFTP, UnicodeString ARemotePath, UnicodeString ALocalPath)
{
 AFTP->ChangeDir("/");
 AFTP->List();

 for( int i = 0; i < AFTP->DirectoryListing->Count; i++)
 {
  if( AFTP->DirectoryListing->Items[i]->ItemType == ditFile )
  {
   AFTP->Get(ARemotePath + AFTP->DirectoryListing->Items[i]->FileName, ALocalPath + AFTP->DirectoryListing->Items[i]->FileName );
  }
 }

 for( int i = 0; i < AFTP->DirectoryListing->Count; i++)
 {
   if( AFTP->DirectoryListing->Items[i]->ItemType == ditDirectory )
   {
    DownloadFolder(AFTP, ARemotePath + AFTP->DirectoryListing->Items[i]->FileName, ALocalPath + AFTP->DirectoryListing->Items[i]->FileName );
    AFTP->ChangeDir(ARemotePath);
   }
 }
}


To C++ nie Delphi, a klasa TIdFTP nie jest klasą wirtualną, więc albo TIdFTP *AFTP i ->, albo TIdFTP &AFTP i .



Widzisz ten porządek w kodzie? Naucz się tego!

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Gepcio
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z funkcją TIdFTP

Nowy postprzez Gepcio » sobota, 6 października 2012, 11:12

Wielkie dzięki! :)
Problem rozwiązany :)
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Chrome

Re: Problem z funkcją TIdFTP

Nowy postprzez Gepcio » sobota, 6 października 2012, 11:33

Drugi problem (piszę tutaj, żeby nie zaśmiecać więc wybaczcie z post pod postem).
Odpalam programik, wszystko ładnie działa ale program się wywala z komunikatem:
Kod: Zaznacz cały
no ftp list parsers have been registered


Przeryłem google ale nie znalazłem odpowiedzi.
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Chrome

Re: Problem z funkcją TIdFTP

Nowy postprzez Cyfrowy Baron » sobota, 6 października 2012, 12:24

Problem z dostępem do serwera FTP, a nie z programem. Musisz prawidłowo określić katalog, z którego pobierasz pliki.

Zaglądałeś już tutaj? http://programowanie.cal.pl/cyfbar/siec.html#siec3
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z funkcją TIdFTP

Nowy postprzez Gepcio » sobota, 6 października 2012, 13:49

Tak, zaglądałem. A katalog to jest po prostu katalog główny, czyli "/", tak więc nie wiem co może nie działać. Spróbuję coś się pobawić.
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Chrome

Re: Problem z funkcją TIdFTP

Nowy postprzez Cyfrowy Baron » sobota, 6 października 2012, 18:51

To pobieranie zawartości katalogu wraz z podkatalogami nie jest takie proste. Ten numer z pętlą nie przejdzie, gdyż po wejściu do podkatalogu trzeba potem z niego wyjść, więc pętla musiałaby przemieszczać się po różnych poziomach.
Nie mam pomysłu, ale to co robisz zadziała tylko dla katalogu, bez pobierania plików razem z podkatalogami.

Pobrałem przykładowy projekt w Delphi dla komponentu TIdFTP ze strony ze wsparciem dla INDY, ale tam nie ma żadnego przykładu na takie pobieranie.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z funkcją TIdFTP

Nowy postprzez polymorphism » sobota, 6 października 2012, 20:21

To C++ nie Delphi, a klasa TIdFTP nie jest klasą wirtualną (...)

Gwoli ścisłości. W C++ przekazywanie obiektów klas przez wartość jest dozwolone*), także brak wirtualności ów klasy nie ma tu związku. Błąd polegał na tym, że klasy VCL-a**) nie mogą być tworzone na stosie, tylko sterta wchodzi w grę. A że wszystkie argumenty funkcji są odkładane (kopiowane) na stosie, to i błąd się pojawił.

___
*) o ile ma - jeśli to konieczne - poprawnie zdefiniowany konstruktor kopiujący.
**) dokładniej wszystkie pochodne klasy TObject.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Pobieranie plików, katalogów i podkatalogów za pomocą IdFTP.

Nowy postprzez Cyfrowy Baron » sobota, 6 października 2012, 21:49

Nie jest to optymalne rozwiązanie, ale działa. Podam cały kod za wyjątkiem hosta, nazwy użytkownika i hasła do konta, które ustawiłem w Object Inspector:

Plik nagłówkowy np. Unit1.h
KOD cpp:     UKRYJ  
private:        // User declarations
        void __fastcall DownloadFolder(TIdFTP *AFTP, UnicodeString ARemotePath, UnicodeString ALocalPath);
        void __fastcall BeginFTPDownload(TIdFTP *AFTP, UnicodeString ARemotePath, UnicodeString ALocalPath);
        TStringList *dirList;


Plik źródłowy np. Unit1.cpp
KOD cpp:     UKRYJ  
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  dirList = new TStringList;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DownloadFolder(TIdFTP *AFTP, UnicodeString ARemotePath, UnicodeString ALocalPath)
{
 AFTP->ChangeDir( ARemotePath );
 AFTP->List();
 String iFileName = "";

 for( int i = 0; i < AFTP->DirectoryListing->Count; i++ )
 {
  String dirItemType = AFTP->DirectoryListing->Items[i]->ItemType;
  iFileName = AFTP->DirectoryListing->Items[i]->FileName;

  if( dirItemType == ditFile )
  {
   AFTP->Get(ARemotePath + iFileName, ALocalPath + iFileName, true, true );
  }
 }

 for( int i = 0; i < AFTP->DirectoryListing->Count; i++ )
 {
  String dirItemType = AFTP->DirectoryListing->Items[i]->ItemType;
  iFileName = AFTP->DirectoryListing->Items[i]->FileName;

  if( dirItemType == ditDirectory && iFileName != "." && iFileName != ".." )
  {
   ForceDirectories( ALocalPath + iFileName + "\\" );
   dirList->Add( ARemotePath + iFileName + "/=" + ALocalPath + iFileName + "\\" );
  }
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BeginFTPDownload(TIdFTP *AFTP, UnicodeString ARemotePath, UnicodeString ALocalPath)
{
 dirList->Clear();
 DownloadFolder( AFTP, ARemotePath, ALocalPath );

 for( int i = 0; i < dirList->Count; i++ )
 {
   DownloadFolder( IdFTP1, dirList->Names[i], dirList->ValueFromIndex[i] );
 }

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 IdFTP1->Connect(); /* połączenie z kontem - włączone autologowanie */
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{ /* uruchomienie pobierania plików */
 BeginFTPDownload( IdFTP1, "/domains/programowanie.cal.pl/public_html/pliki/", "c:\\temp\\" );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdFTP1Status(TObject *ASender, const TIdStatus AStatus,
                  const UnicodeString AStatusText)
{
 Memo1->Lines->Add( IntToStr(AStatus)+ ". " + AStatusText );
 Application->ProcessMessages();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
 IdFTP1->Disconnect();
 delete dirList;
}
//---------------------------------------------------------------------------


Na moim koncie to działa, czyli pobierane są wszystkie pliki i podkatalogi z zadanego katalogu z zachowaniem struktury katalogów.

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Gepcio
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z funkcją TIdFTP

Nowy postprzez Gepcio » poniedziałek, 8 października 2012, 11:22

Dzięki za pomoc ale próbowałem tym sposobem i na razie program się wykrzacza z błędem:
Obrazek

Więc nadal stoję w miejscu.
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Chrome

Re: Problem z funkcją TIdFTP

Nowy postprzez polymorphism » poniedziałek, 8 października 2012, 11:48

KOD cpp:     UKRYJ  
private:        // User declarations
        ...

        TStringList *dirList; // <--- pole klasy
        ...


// Plik źródłowy np. Unit1.cpp
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
        TStringList *dirList = new TStringList; //<--- inicjalizacja lokalnego wskaźnika
}

...

void __fastcall TForm1::BeginFTPDownload(...)
{
        dirList->Clear(); //<--- odwołanie do nieinicjalizowanego pola klasy TForm1::dirList
        ...

        DownloadFolder( ..., dirList->Names[i], dirList->ValueFromIndex[i] ); //<--- jw.
        ...
}
 
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Gepcio
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z funkcją TIdFTP

Nowy postprzez Cyfrowy Baron » poniedziałek, 8 października 2012, 11:53

Poprawiłem już ten błąd! Powinno być:

KOD cpp:     UKRYJ  
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
  dirList = new TStringList;
}


Testy przeprowadzałem na obiekcie globalnym, ale przepisując kod postanowiłem dla jasności umieścić deklarację obiektu w sekcji private pliku nagłówkowego, jednak do konstruktora klasy formularza przepisałem tak jak miałem u siebie i stąd ten błąd. :?

Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
Gepcio
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Problem z funkcją TIdFTP

Nowy postprzez Gepcio » poniedziałek, 8 października 2012, 12:09

Teraz wszystko działa jak należy! Dziękuję!! :)
Avatar użytkownika
Gepcio
Bladawiec
Bladawiec
 
Posty: 10
Dołączył(a): niedziela, 20 maja 2012, 11:52
Podziękował : 4
Otrzymał podziękowań: 1
System operacyjny: Windows 7 Ultimate
Kompilator: Embarcadero RAD Studio 2010
C++ Builder 2010 Update 5
Gadu Gadu: 0
    Windows 7Chrome


Powrót do Aplikacje sieciowe

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 17 gości

cron