Qt的FTP网络编程Word文档下载推荐.docx
- 文档编号:17677253
- 上传时间:2022-12-08
- 格式:DOCX
- 页数:13
- 大小:24.47KB
Qt的FTP网络编程Word文档下载推荐.docx
《Qt的FTP网络编程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Qt的FTP网络编程Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
{
QCoreApplication
app(argc,
argv);
QStringList
args
=
QCoreApplication:
:
arguments();
if
(args。
count()
!
2)
std:
cerr
〈〈
”Usage:
myftpget
url”
〈<
std:
endl
"
Example:
<
〈
ftp:
//
:
endl;
return
1;
}
MyFtpGet
getter;
(!
getter.getFile(QUrl(args[1])))
QObject:
connect(&getter,
SIGNAL(done()),
&
app,
SLOT(quit()));
app.exec();
}
我们看到,这里使用的是QCoreApplication,而不是QApplication,这样做是为了防止在编译时连接QtGui程序库。
另外,函数QCoreApplication:
arguments()返回的命令行参数用作QStringList,其第一项是被调用的程序的名称,这里的任何Qt参数,比如-style等,都将被删除.Main()函数的重点在于建立MyFtpGet对象并调用getFile(),如果调用成功,就进入事件循环,直到下载结束为止。
我们看到,所有的活都是由MyFtpGet子类来干的,其定义如下:
class
public
QObject
Q_OBJECT
public:
MyFtpGet(QObject
*parent
0);
bool
getFile(const
QUrl
url);
signals:
void
done();
private
slots:
ftpDone(bool
error);
private:
QFtp
ftp;
QFile
file;
};
这个类具有一个公共函数getFile(),用来检索URL指定的文件.类QUrl提供了一个高级接口,用来提取URL的各个部分,如文件名、路径、协议和端口等等.MyFtpGet具有一个私有的槽,即ftpDone(),当我们的文件传输完成时,就会调用该函数;
另外,MyFtpGet还有一个信号,即done(),当文件下载后就会发出该信号.除此之外,这个类还有两个私有变量,分别是变量ftp和变量file。
前者类型为QFtp,用来封装至FTP服务器的连接;
后者用来将下载的文件写入硬盘。
MyFtpGet:
*parent)
QObject(parent)
connect(&ftp,
SIGNAL(done(bool)),
this,
SLOT(ftpDone(bool)));
在构造函数中,我们将信号QFtp:
done(bool)连到了私有的槽ftpDone(bool)上,当处理完所有请求后,QFtp就会发出信号done
(bool).参数bool的作用是指示有没有出错.
现在让我们看看getFile()函数:
MyFtpGet:
&url)
url。
isValid())
{
”Error:
Invalid
URL”
false;
(url。
scheme()
ftp”)
Error:
URL
must
start
with
'
ftp:
’"
endl;
(url.path()。
isEmpty())
Error:
has
no
path”
QString
localFileName
QFileInfo(url.path()).fileName();
(localFileName.isEmpty())
myftpget。
out"
;
file.setFileName(localFileName);
(!
file。
open(QIODevice:
WriteOnly))
Cannot
write
file
”
qPrintable(file。
fileName())
”:
qPrintable(file.errorString())
ftp.connectToHost(url。
host(),
url.port(21));
ftp.login();
ftp.get(url。
path(),
&file);
ftp。
close();
true;
GetFile()函数首先检查传递给它的URL,如果有问题,它会向cerr打印错误信息,并返回false,指示下载失败。
注意,在这里,我们没有要求用户建立一个文件名,相反,我们设法利用URL本身来生成一个文件名。
如果文件打开失败,会打印错误信息并返回false。
接下来,我们使用QFtp对象执行一个由四条FTP命令组成的命令序列.调用url.port(21)后,将返回URL中指定的端口号,如果URL中没有指定端口号的话,将返回端口21。
此外,因为没有向函数login()提供用户名或者口令,所以该函数将尝试匿名登录。
给get()的第二个参数规定用于输出的I/O设备.
在Qt的事件循环中,将对FTP命令进行排队并执行它们。
当所有命令执行完毕后,QFtp将发出信号done(bool),前面已经看到,该信号已经在构造函数中连到了ftpDone(bool)上,那就再看看该函数到底做什么:
error)
(error)
”Error:
qPrintable(ftp.errorString())
}
else
File
downloaded
as
file.close();
emit
done();
FTP命令执行后,我们马上关闭该文件,并发出我们自己done()信号。
你也许觉得奇怪,为什么会在这里关闭文件呢?
好像应该在getFile()函数末尾调用ftp.close()后关闭才对呀?
别忘了,FTP命令是异步执行的,也许它们在执行时函数getFile()早就已经返回了.只有当QFtp对象的done()信号发出后,我们才能确切的知道下载已经结束,这时关闭文件才是安全的.
QFtp提供了许多FTP命令,它们是connectToHost()、login()、close()、list()、cd()、get()、put()、remove()、mkdir()、rmdir()和rename()。
这些函数都会发出一个FTP命令,并返回一个标识该命令的ID号.此外,还可以控制传输模式,默认为被动模式,以及传输类型,默认时为二进制类型。
另外,所有FTP命令都可以通过rawCommand()来执行,举例来说,可以像下面这样执行SITECHMOD命令:
ftp.rawCommand("
SITECHMOD755fortune"
);
当QFtp执行一个命令时,它会发出commandStarted(int)信号;
当命令执行完成后,它会发出commandFinished(int,bool)信号,其中参数int表示该命令的ID号。
如果想了解某个命令的执行情况,可以在调度该命令时记下其ID号,然后通过跟踪ID号就能了解相关情况。
举例来说:
url)
..。
connectId
ftp.connectToHost(url.host(),
port(21));
loginId
login();
getId
ftp.get(url.path(),
file);
closeId
close();
true;
ftpCommandStarted(int
id)
(id
==
connectId)
Connecting..。
”
}
loginId)
Logging
in。
。
除此之外,还有一种方法可以了解命令执行情况,那就是与QFtp的stateChanged()信号相连接,因为每当该连接进入一个新的状态时(QFtp:
Connecting、QFtp:
Connected、QFtp:
LoggedIn等等),QFtp总会发出相应的stateChanged()信号。
不过在大部分情况下,我们只对命令序列的整体情况感兴趣,而不是单独的某条命令,这时就可以直接与done(bool)信号连接,因为命令队列为空时,就会发出该信号。
当遇到错误时,QFtp会自动清空命令队列,也就是说如果连接或者注册失败的话,队列后面的命令就没有机会执行了。
如果我们在出错之后使用同一个QFtp对象重新发出命令的话,这些命令将被重新排队并执行。
在本程序的。
pro文件中,需要用下列行来连接QtNetwork库:
QT+=network
现在,我们将考察一个更加复杂的例子:
命令行程序yourftpget,它将下载一个FTP目录中的所有文件,并递归下载该目录下的所有子目录中的文件.有关代码如下所示:
Yourftpget
public:
Yourftpget(QObject
*parent
getDirectory(const
&url);
signals:
slots:
ftpListInfo(const
QUrlInfo
urlInfo);
processNextDirectory();
ftp;
QList<
*〉
openedFiles;
currentDir;
currentLocalDir;
pendingDirs;
};
这里的起始目录由QUrl指定,然后使用getdirectory()函数进行设置.
Yourftpget:
connect(&
ftp,
SIGNAL(done(bool)),
ftp,
SIGNAL(listInfo(const
&)),
this,
SLOT(ftpListInfo(const
&)));
在构造函数中,我们建立了两个信号–槽连接。
当为每个检索的文件请求目录清单时,QFtp就会发出listInfo(constQUrlInfo)信号。
这个信号连接到一个称为ftplistinfo()的槽上,该函数会下载给定URL相关联的文件。
Yourftpget:
false;
(url.scheme()
”ftp"
)
’ftp:
’”
path
url.path();
(path。
isEmpty())
/”;
pendingDirs。
append(path);
调用getDirectory()函数时,它首先进行必要的检查,如果一切正常的话,它就尝试建立一个FTP连接。
它记下必须处理的路径,并调用processNextDirectory()开始下载根目录。
processNextDirectory()
pendingDirs.isEmpty())
currentDir
pendingDirs.takeFirst();
currentLocalDir
downloads/”
+
currentDir;
QDir("
).mkpath(currentLocalDir);
cd(currentDir);
ftp.list();
函数processNextDirectory()从pendingDirs列表中取得第一个远程目录,然后在本地文件系统中创建一个对应的目录,之后指示QFtp对象切换到该远程目录中来列出目录下的文件。
List()每处理一个文件,它都会发出一个listInfo()信号,该信号会调用ftpListInfo()槽。
如果处理完所有目录,该函数会发出一个done()信号来指示下载完成。
urlInfo)
(urlInfo.isFile())
(urlInfo.isReadable())
*file
new
QFile(currentLocalDir
”/”
urlInfo.name());
file->
”Warning:
qPrintable(QDir:
toNativeSeparators(
file—>
fileName()))
qPrintable(file—>
errorString())
return;
ftp.get(urlInfo.name(),
file);
openedFiles。
append(file);
(urlInfo。
isDir()
!
urlInfo.isSymLink())
pendingDirs.append(currentDir
”/”
urlInfo。
name());
槽ftpListInfo()的参数urlInfo提供了远程文件的详细信息,如果该文件是一个常规文件并且可读的话,我们就调用get()来下载之。
为此,用new分配一个QFile对象来处理下载,并将指向它的指针放在openedFiles列表中.如果QUrlInfo存放的是远程目录的详细信息,而非一个符号连接的信息,那么就把这个目录添加到pendingDirs列表中。
之所以不用符号连接,是因为它常常导致无限递归。
cout
Downloaded
qPrintable(currentDir)
to
qPrintable(QDir:
QDir(currentLocalDir)。
canonicalPath()));
qDeleteAll(openedFiles);
openedFiles.clear();
processNextDirectory();
当全部FTP命令都结束时,或者出现错误时,将会调用槽ftpDone()。
为了防止内存泄漏,需要删除QFile对象。
最后,我们调用processNextDirectory()。
只要还有未处理的目录,就要对列表中的下一个目录进行新一轮的处理;
否则,停止下载并发出done()信号.如果没有出现错误的话,FTP命令序列和信号会像下面一样:
connectToHost(host,
port)
login()
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Qt FTP 网络 编程