У меня долго не получалось заставить QFtp соединяться с сервером и загрузить файлы. И я решил поделиться рецептом, тем более не все топики, которые я здесь видел, заканчивались успешно..
void Foo::Upload()
{
this->ftpConnection = new QFtp(this);
connect(ftpConnection, SIGNAL(stateChanged(int)), this, SLOT(ftpStateChanged()));
connect(ftpConnection, SIGNAL(done(bool)), this, SLOT(ftpConnected(bool)));
ftpConnection->connectToHost("host", 21);
ftpConnection->login("user", "pass");
}
void Foo::ftpConnected(bool hasError)
{
if(hasError)
{
QString error;
switch(ftpConnection->error())
{
case QFtp::HostNotFound:
{
error = "не удалось обнаружить адрес";
break;
}
default:
{
error = ftpConnection->errorString().replace("\n", " "); // errorString() часто содержит \n
break;
}
}
this->logger->addRecord("Ошибка соединения с FTP-сервером: ") + error; // мой логгер
}
void Foo::ftpStateChanged()
{
if(ftpConnection->state() == QFtp::LoggedIn)
{
ftpConnection->cd("dir1/dir2");
if(ftpConnection->error() != QFtp::NoError)
{
logger->addRecord("Ошибка соединения с FTP-сервером: ") + ftpConnection->errorString());
return;
}
else
{
QDir dir("c:/uploads");
if(!dir.exists())
{
logger->addRecord("Указанная папка не существует");
return;
}
QStringList fileList = dir.entryList(QDir::Files);
for(QStringList::const_iterator it = fileList.begin(); it != fileList.end(); it++)
{
QFile file("c:/uploads/" + *it);
if(file.open(QIODevice::ReadOnly))
{
ftpConnection->put(file.readAll(), *it);
if(ftpConnection->error() == QFtp::NoError)
{
logger->addRecord("Файл успешно выгружен: " + *it);
file.remove();
}
else
{
logger->addRecord("Не удалось выгрузить файл: " + *it);
}
}
}
ftpConnection->close();
}
}
}
Как этим пользоваться?
QFtp* ftpConnection - локальная переменная класса
void ftpStateChanged(), void ftpConnected(bool) - методы объявленные как public slots
Что делает этот класс? Соединяется с ftp-сервером по адресу 'host' (префикс ftp:// можно не указывать) порт 21, по логину 'user' / паролю 'pass' и загружает в удаленную папку dir1/di2 все файлы, содержащиеся в локальной c:\uploads, после чего удаляет их. Всё прописано в коде напрямую.
Всё происходящее журналируется через некий класс logger::addRecord(const QString&).