2009-11-02 82 views
1

我想实现在单独的线程中下载文件并存储该文件,但我无法找到一个合适的方式来实现这个没有恶意延迟(相当频繁下载小文件,所以信号+插槽太慢)。 我想达到什么: (伪码)同步的C++/Qt下载文件

request file; 
wait for download finishing, timeout or error; 
save downloaded file; 

我宁愿用QNetworkAccessManager如果可能的例子。 谢谢你的任何提示。

编辑:只需要清楚,我想要的信号和插槽不是因为设计和速度的缺乏。

编辑2:此下载只是关于同步部分的下载文件,线程是没有问题的。 问题是,QT没有提供这样做的API,我不热衷于等待。

EDIT3:示例代码像它应该工作,但不会:

QNetworkAccessManager net; 
QNetworkReply *re (net.get(QNetworkRequest(QUrl(Qstring("www.blah.org/key"))))); 
if (re->waitForReadyRead(-1)) //! @bug this does not work as supposed, waitForRead returns false and returns INSTANTLY!! 
    qDebug() << "ReadyRead yeha!!!"; 
if (re->error()) { 
    qDebug() << "Can't download" << re->url().toString() 
      << ":" << re->errorString(); 
} else { 
    img->load(re->readAll()); 
    qDebug() << "Savin IMG"; 
} 
delete re; 
+0

似乎没有本地事件循环你的“重新”甚至不知道它完成。我遇到过类似的问题。附:不要直接删除QNetworkReply,请使用“deleteLater”。 – QtRoS 2015-02-17 21:42:42

回答

1

我需要类似的东西,但出于不同的原因。由于QHttp和QNetworkAccessManager都是异步的,你可以使用单独的事件循环,所以可以找到一个基于QHttp的完整示例here。对QNetworkAccessManager进行修改应该不会太困难。

值得一提的是,您对信号/插槽“很慢”的印象可能是错误的。你有没有真正分析你的代码来确定这一点?

无论您为信号/插槽付出的代价是多少,在查看单个文件下载所花费的时间时,可能会忽略不计。更重要的是,用这种方式做事非常“非Qt”。这些类是这样设计的。

在一天如果你确实从信号/插槽痛苦(这又是,怀疑)结束后,我会建议不要使用Qt为这个特殊的任务,也许普通的旧的C座是一个更好的主意(或者在它们周围使用薄的包装来保存可能需要额外工作的错误处理)。

+0

嗯,我希望不必在并行线程中使用exec()。 你给了我一个想法:-D谢谢 – drahnr 2009-11-03 14:44:50

+0

确定3小时的搜索后,我摔倒了这个: http://wiki.qtcentre.org/index.php?title=Keeping_the_GUI_Responsive 它和你建议我一样,我这样做,它的工作原理。谢谢。你解决了这个问题:-) – drahnr 2009-11-03 23:44:34

0

同步网络访问是一个坏主意,因为它会导致不良的用户界面体验。除了你认为的错误不是一个错误。它只是错误地记录。

+0

同步这些对于测试工具,单元测试甚至服务器逻辑来说都是非常好的事情/这些东西只是不能实时响应。 – 2015-06-26 20:38:15