通过HTTPS从POCO StreamCopier获取文件下载进度
Getting file download progress from POCO StreamCopier through HTTPS
我一直在使用WinHTTP和WinInet开发HTTP客户端,最近想到了切换到POCO,因为它为HTTP实现提供了最好的API。
我确实让它工作了,但问题是我想通过定期查询流或通过某些事件处理来了解文件的下载进度。
开始搜索可以执行此操作的 API,然后在 C++ (Poco/Boost) 中遇到了这个包含进度信息的 Http 上传,该上传讨论了使用 CountingOutputStream 获取文件上传方案的进度。我觉得这是不完整的,并没有按照我预期的方式做,根本没有使用该 CountingStream 的实际实现。
我开始知道通过CountingInputStream可以实现,但我不知道如何使用HttpStreamFactory的公开调用返回的流来做到这一点。是否可以使用它以多个块读取流?或定期查询读取的数据量,以便我可以通知 UI?
这是我的代码:
bool HttpClientConnection::DownloadFile ( const std::string& file_url, const std::string file_location )
{
try
{
std::string complete_page_url = "";
std::ofstream file_stream;
std::unique_ptr<std::istream> pStr = nullptr;
if (isSecureConnection)
{
complete_page_url = "https://";
}
else
{
complete_page_url = "http://";
}
{
complete_page_url = serverHostName + file_url;// assuming the file url itself will contain leading forward slash
}
// Create the URI from the URL to the file.
URI uri(complete_page_url);
//std::auto_ptr<std::istream>pStr(URIStreamOpener::defaultOpener().open(uri);
//StreamCopier::copyStream(*pStr.get(), std::cout);
if (isSecureConnection)
{
std::unique_ptr<HTTPSStreamFactory> https_stream_factory = nullptr;
if (_buseProxy)
{
https_stream_factory = std::unique_ptr<HTTPSStreamFactory>(new HTTPSStreamFactory(proxyHostName, proxyPort, getProxyUserName(), getProxyPassword()));
}
else
{
https_stream_factory = std::unique_ptr<HTTPSStreamFactory>(new HTTPSStreamFactory());
}
if (https_stream_factory)
{
pStr = std::unique_ptr<std::istream>(https_stream_factory->open(uri));
}
}
else
{
std::unique_ptr<HTTPStreamFactory> http_stream_factory = nullptr;
if (_buseProxy)
{
http_stream_factory = std::unique_ptr<HTTPStreamFactory>(new HTTPStreamFactory(proxyHostName, proxyPort, getProxyUserName(), getProxyPassword()));
}
else
{
http_stream_factory = std::unique_ptr<HTTPStreamFactory>(new HTTPStreamFactory());
}
if (http_stream_factory)
{
pStr = std::unique_ptr<std::istream>(http_stream_factory->open(uri));
}
}
if (pStr)
{
file_stream.open(file_location, ios::out | ios::trunc | ios::binary);
StreamCopier::copyStream(*pStr.get(), file_stream);
file_stream.close();
}
return true;
}
catch (Exception& exc)
{
if (httpLogger)
{
httpLogger->log(dcLogger::LOG_INFO, "HttpClient:: Exception in DownloadFile , error code: %d", exc.code());
}
}
return false;
}
将文件输出流对象传递给 CountingOutputStream,并以计数输出流作为参数启动计时器。计时器会定期调用,直到数据传输完成,该数据传输获取写入的字节数并通知注册该事件的人。那奏效了!.
shared_ptr<CountingOutputStream> cout_stream = shared_ptr<CountingOutputStream>(new CountingOutputStream(file_stream));
if (callback && callback_interval_in_millis > 0)
{
shared_ptr<FileProgressHandler> file_progress = shared_ptr<FileProgressHandler>(new FileProgressHandler(cout_stream, file_size, callback));
if (file_progress)
{
TimerCallback<FileProgressHandler> callback(*(file_progress.get()), &FileProgressHandler::onTimer);
timer = shared_ptr<Timer>(new Timer(0, callback_interval_in_millis));
if (timer)
{
timer->start(callback);
}
}
StreamCopier::copyStream(*pStr.get(), *cout_stream);
if (timer)
{
timer->stop();
}
}
void onTimer(Timer& timer)
{
try
{
if (progress_callback)
{
int data_processed = 0;
counting_io_stream ? data_processed = counting_io_stream->chars() : __noop;
if (data_processed != total_processed_data)
{
total_processed_data = data_processed;
int percent = (100 * total_processed_data) / file_size;
progress_callback(percent);
}
}
}
catch(const std::bad_function_call& e)
{
}
catch(const std::bad_weak_ptr& e)
{
}
catch(const std::exception& e)
{
}
}
相关文章:
- C++文本文件的获取线
- 无法从 XML 文件中获取值
- 使用 Libcurl 库进行文件下载
- 从我的 2DgridArray 中的文本文件中获取每个字符
- 如何从主.cpp中的cpp文件中获取功能结果?
- 如何从wav文件中获取采样率?
- 如何逐行从文件中获取单词,并在C++中用分号分隔?
- 当在C++中找到所需的行时,如何从文件中获取接下来的 n 行
- 从文件中获取产品总数
- 如何在 c++ 中从文本文件中获取特定单词?
- 是否可以使用 std::文件系统获取根名称列表?
- 如何从 3d 对象文件中获取 3d 坐标
- 有没有办法使用 mongocxx 驱动程序从 GridFS 集合的文件下载任意范围?
- 使用libgdal从文件中获取地形的轮廓
- 从 .so/.o 文件中获取 C/cpp 中的静态库列表
- 如何从二进制文件中获取应用程序的版本号?
- 如何交替从文件中获取一行数据和一个整数?
- 使用 libcurl C++将文件下载到 Ubuntu,简单示例不起作用
- 通过HTTPS从POCO StreamCopier获取文件下载进度
- 如何在下载文件之前获取文件名