gpt4 book ai didi

c++ - 通过 HTTPS 从 POCO StreamCopier 获取文件下载进度

转载 作者:可可西里 更新时间:2023-11-01 16:36:19 24 4
gpt4 key购买 nike

我一直在使用 WinHTTP 和 WinInet 开发 HTTP 客户端,最近想到了切换到 POCO,因为它为 HTTP 实现提供了最好的 API。

我确实让它工作了,但问题是我想通过定期查询流或通过一些事件处理来了解文件的下载进度。

开始搜索可以执行此操作的 API,然后发现了这个 Http upload with progress info, in C++ (Poco/Boost)讨论了使用 CountingOutputStream 获取文件上传场景的进度。我觉得那是不完整的,没有按照我的预期那样做,根本没有使用那个 CountingStream 的实际实现。

我开始知道可以通过 CountingInputStream 实现,但我不知道如何使用 HttpStreamFactory 的公开调用返回的流来实现。是否可以使用它读取多个 block 中的流?或者定期查询读取的数据量以便通知 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++ - 通过 HTTPS 从 POCO StreamCopier 获取文件下载进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44474102/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com