Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QT 4: ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ GUI Π½Π° Π‘++Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 80

Автор Жасмин Π‘Π»Π°Π½ΡˆΠ΅Ρ‚

Класс QFtp ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ нСсколько FTPβ€”ΠΊΠΎΠΌΠ°Π½Π΄, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ connectToHost(), login(), close(), list(), cd(), get(), put(), remove(), mkdir(), rmdir() ΠΈ rename(). ВсС эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡŽΡ‚ ΠΊΠ°ΠΊΡƒΡŽ-Ρ‚ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ FTP ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ число, ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‰Π΅Π΅ эту ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ. МоТно Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒ Ρ€Π΅ΠΆΠΈΠΌΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ пассивная ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π°) ΠΈ Ρ‚ΠΈΠΏΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡ΠΈ (Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΉ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ).

ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ FTP ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ rawCommand(). НиТС приводится ΠΏΡ€ΠΈΠΌΠ΅Ρ€ выполнСния ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ SITE CHMOD:

ftp.rawCommand("SITE CHMOD 755 fortune");

QFtp Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ сигнал commandStarted(int) Π² Π½Π°Ρ‡Π°Π»Π΅ выполнСния ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΈ сигнал commandFinished(int, bool) послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ выполнСния ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹. ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ‚ΠΈΠΏΠ° int являСтся числом, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ. Если ΠΌΡ‹ собираСмся ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ выполнСния ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ эти ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ ΠΏΡ€ΠΈ постановкС ΠΊΠΎΠΌΠ°Π½Π΄ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ. ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΠ΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ² обСспСчиваСт Π±ΠΎΠ»Π΅Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΡƒΡŽ ΠΎΠ±Ρ€Π°Ρ‚Π½ΡƒΡŽ связь с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ. НапримСр:

01 bool FtpGet::getFile(const QUrl &url)

02 {

03 …

04 connectId = ftp.connectToHost(url.host(), url.port(21));

05 loginId = ftp.login();

06 getId = ftp.get(url.path(), &file);

07 closeId = ftp.close();

08 return true;

09 }


10 void FtpGet::ftpCommandStarted(int id)

11 {

12 if (id == connectId) {

13 сСгг << "Connecting..." << endl;

14 } else if (id == loginId) {

15 cerr << "Logging in..." << endl;

16 …

17 }

Π”Ρ€ΡƒΠ³ΠΎΠΉ способ обСспСчСния ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΉ связи Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΊ сигналу stateChanged() класса QFtp, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ гСнСрируСтся ΠΏΡ€ΠΈ всяком ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ состояния соСдинСния (QFtp::Connecting, QFtp::Connected, QFtp::LoggedIn ΠΈ Ρ‚.Π΄.).

Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ нас интСрСсуСт Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ исполнСния всСй ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄, Π° Π½Π΅ ΠΊΠ°ΠΊΠΈΡ…-Ρ‚ΠΎ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ просто ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ сигнал done(bool), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ гСнСрируСтся всякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄ становится пустой.

ΠŸΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки QFtp автоматичСски ΠΎΡ‡ΠΈΡ‰Π°Π΅Ρ‚ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄. Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ Π½Π΅ΡƒΠ΄Π°Ρ‡Π½ΠΎΠΌ подсоСдинСнии ΠΈΠ»ΠΈ Π²Ρ…ΠΎΠ΄Π΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ Π² систСму ΠΎΡΡ‚Π°Π²ΡˆΠΈΠ΅ΡΡ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ выполнятся. Если ΠΌΡ‹ послС возникновСния ошибки Π·Π°Π΄Π°Π΄ΠΈΠΌ Π½ΠΎΠ²Ρ‹Π΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ с использованиСм Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° QFtp, ΠΎΠ½ΠΈ Π±ΡƒΠ΄ΡƒΡ‚ поставлСны Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Ρ‹.

Π’ Ρ„Π°ΠΉΠ» прилоТСния .pro Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ строку для сборки прилоТСния совмСстно с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ QtNetwork:

QT += network

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ рассмотрим Π±ΠΎΠ»Π΅Π΅ слоТный ΠΏΡ€ΠΈΠΌΠ΅Ρ€. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ строки spider (ΠΏΠ°ΡƒΠΊ) скачиваСт всС Ρ„Π°ΠΉΠ»Ρ‹, располоТСнныС Π² ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ FTP—сСрвСра, рСкурсивно просматривая ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π΅Π³ΠΎ ΠΏΠΎΠ΄ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³. Вся Π»ΠΎΠ³ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΡΠ΅Ρ‚ΡŒΡŽ содСрТится Π² классС Spider:

01 class Spider : public QObject

02 {

03 Q_OBJECT

04 public:

05 Spider(QObject *parent = 0);

06 bool getDirectory(const QUrl &url);

07 signals:

08 void done();

09 private slots:

10 void ftpDone(bool error);

11 void ftpListInfo(const QUrlInfo &urlInfo);

12 private:

13 void processNextDirectory();

14 QFtp ftp;

15 QList<QFile *> openedFiles;

16 QString currentDir;

17 QString currentLocalDir;

18 QStringList pendingDirs;

19 };

ΠΠ°Ρ‡Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ опрСдСляСтся ΠΊΠ°ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ° QUrl ΠΈ устанавливаСтся ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getDirectory().

01 Spider::Spider(QObject *parent)

02 : QObject(parent)

03 {

04 connect(&ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));

05 connect(&ftp, SIGNAL(listInfo(const QUrlInfo &)),

06 this, SLOT(ftpListInfo(const QUrlInfo &)));

07 }

Π’ конструкторС ΠΌΡ‹ устанавливаСм Π΄Π²Π° соСдинСния сигнал—слот. Когда ΠΌΡ‹ Π²Ρ‹Π΄Π°Π΅ΠΌ запрос Π½Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ списка элСмСнтов ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° Π² getDirectory(), QFtp Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ сигнал listInfo(const QUrlInfo &) для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½Π°ΠΉΠ΄Π΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠΌΠ΅Π½ΠΈ. Π­Ρ‚ΠΎΡ‚ сигнал ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ ΠΊ слоту с ΠΈΠΌΠ΅Π½Π΅ΠΌ ftpListInfo(), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ скачиваСт Ρ„Π°ΠΉΠ» ΠΈΠ· сСти ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ адрСсу URL.

01 bool Spider::getDirectory(const QUrl &url)

02 {

03 if (!url.isValid()) {

04 cerr << "Error: Invalid URL" << endl;

05 return false;

06 }

07 if (url.scheme() != "ftp") {

08 cerr << "Error: URL must start with 'ftp:'" << endl;

09 return false;

10 }

11 ftp.connectToHost(url.host(), url.port(21));

12 ftp.login();

13 QString path = url.path();

14 if (path.isEmpty())

15 path = "/";

16 pendingDirs.append(path);

17 processNextDirectory();

18 return true;

19 }

Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ getDirectory() начинаСтся с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… основных ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ, ΠΈ Ссли всС Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, дСлаСтся ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ FTP—соСдинСниС. Она отслСТиваСт ΠΏΡƒΡ‚ΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ, ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ processNextDirectory(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°Ρ‡Π°Ρ‚ΡŒ скачиваниС ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠ³ΠΎ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°.

01 void Spider::processNextDirectory()

02 {

03 if (!pendingDirs.isEmpty()) {

04 currentDir = pendingDirs.takeFirst();

05 currentLocalDir = "downloads/" + currentDir;

06 QDir(".").mkpath(currentLocalDir);

07 ftp.cd(currentDir);

08 ftp.list();

09 } else {

10 emit done();

11 }

12 }

Ѐункция processNextDirectory() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ ΠΈΠ· списка ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΎΠ², ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ, pendingDirs, ΠΈ создаСт ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ Π² локальной Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС. ПослС этого ΠΎΠ½Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ QFtp Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ измСнСния ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° Π½Π° принятый Сю ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ ΠΈ Π·Π°Ρ‚Π΅ΠΌ получСния списка Π΅Π³ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ². Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°, ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ list(), гСнСрируСтся сигнал listInfo(), приводящий ΠΊ Π²Ρ‹Π·ΠΎΠ²Ρƒ слота ftpListInfo().

Когда всС ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΌΠΈ, эта функция Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ сигнал done(), ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‰ΠΈΠΉ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ скачивания.

01 void Spider::ftpListInfo(const QUrlInfo &urlInfo)

02 {

03 if (urlInfo.isFile()) {

04 if (urlInfo.isReadable()) {

05 QFile *file = new QFile(currentLocalDir + "/"

06 + urlInfo.name());

07 if (!file->open(QIODevice::WriteOnly)) {

08 cerr << "Warning: Cannot open file << qPrintable(

09 QDir::convertSeparators(file->fileName()))

10 << endl;

11 return;

12 }

13 ftp.get(urlInfo.name(), file);

14 openedFiles.append(file);

15 }

16 } else if (urlInfo.isDir() && !urlInfo.isSymLink()) {

17 pendingDirs.append(currentDir + "/" + urlInfo.name());

18 }

19 }

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ urlInfo слота ftpListInfo() содСрТит ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ Ρ„Π°ΠΉΠ»Π΅ Π² сСти. Если это ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» (Π½Π΅ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³) ΠΈ Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ get() для Π΅Π³ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ. ΠžΠ±ΡŠΠ΅ΠΊΡ‚ QFile, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»Π°, создаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° new, ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π½Π΅Π³ΠΎ хранится Π² спискС openedFiles.

Если содСрТащиСся Π² QUrlInfo свСдСния ΠΎΠ± ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π΅ говорят, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π½Π΅ являСтся символичСской связью, этот ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ добавляСтся ΠΊ списку pendingDirs. ΠœΡ‹ пропускаСм символичСскиС связи, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ΠΈ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠ³ΡƒΡ‚ привСсти ΠΊ бСсконСчной рСкурсии.

01 void Spider::ftpDone(bool error)

02 {

03 if (error) {

04 cerr << "Error: " << qPrintable(ftp.errorString()) << endl;

05 } else {

06 cout << "Downloaded " << qPrintable(currentDir) << " to "

07 << qPrintable(QDir::convertSeparators(

08 QDir(currentLocalDir).canonicalPath()));

09 }

10 qDeleteAll(openedFiles);

11 openedFiles.clear();

12 processNextDirectory();

13 }

Π‘Π»ΠΎΡ‚ ftpDone() вызываСтся послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ всСх ΠΊΠΎΠΌΠ°Π½Π΄ FTP ΠΈΠ»ΠΈ ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки. ΠœΡ‹ удаляСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ QFile для прСдотвращСния ΡƒΡ‚Π΅Ρ‡Π΅ΠΊ памяти, Π° Ρ‚Π°ΠΊΠΆΠ΅ для закрытия всСх Ρ„Π°ΠΉΠ»ΠΎΠ². НаконСц, ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ processNextDirectory(). Если ΠΊΠ°ΠΊΠΈΠ΅-Π½ΠΈΠ±ΡƒΠ΄ΡŒ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³ΠΈ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ, вСсь процСсс повторяСтся для ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° Π² спискС; Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС скачиваниС Ρ„Π°ΠΉΠ»ΠΎΠ² прСкращаСтся ΠΈ гСнСрируСтся сигнал done().

Если ошибок Π½Π΅Ρ‚, ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄ FTP ΠΈ сигналов Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ:

connectToHost(host, port)

login()

cd(directory_1)

list()

emit listInfo(file_1_1)

get(file_1_1)

emit listInfo(file_1_2)

get(file_1_2)

…

emit done()

…

cd(directory_N)

list()

emit listInfo(file_N_1)

get(file_N_1)

emit listInfo(file_N_2)

get(file_N_2)