使用 cURLpp 进行多次下载的进度指示器

发布于 2024-12-09 19:26:36 字数 916 浏览 0 评论 0原文

我正在编写一个下载多个文件的程序(目前只有 2 个)。我试图使用 ProgressFunction 回调让它显示每次下载的进度条。我遇到的问题是我无法找出区分两个文件之间的进度的方法。现在正在两者之间切换。我尝试寻找任何进一步的文档,但他们网站上的 API 链接似乎已损坏,除了一些基本示例之外,没有太多内容。

    //ProgressCalback
    double ProgressCallBack(double dltotal, double dlnow, double ultotal, double ulnow){
       double progress = (dlnow/dltotal) * 100;
       std::ostringstream strs;
       float percent = floorf(progress * 100) / 100;
       strs << percent;
       printf("%s\t%d\t%d\t%d\t%d\n", strs.str().c_str(),dltotal, dlnow, ultotal, ulnow);
       return 0;
    };

    curlpp::options::ProgressFunction progressBar(ProgressCallBack);
    request1.setOpt(new curlpp::options::Url(url1));
    request1.setOpt(new curlpp::options::Verbose(false));
    request1.setOpt(new curlpp::options::NoProgress(0));
    request1.setOpt(progressBar);

我不完全确定我的代码的哪一部分是相关的,所以这里是与进度回调相关的部分。任何帮助将不胜感激。

I am writing a program that downloads multiple files (at the moment its only 2). I am trying to get it to display a progress bar for each download using the ProgressFunction callback. The problem I am running into is I cannot figure out a way to differentiate between the progress between the two files. Right now it is switching between the two. I have tried looking for any further documentation but it seems the API link is broken on their site and there is not much other than some basic examples.

    //ProgressCalback
    double ProgressCallBack(double dltotal, double dlnow, double ultotal, double ulnow){
       double progress = (dlnow/dltotal) * 100;
       std::ostringstream strs;
       float percent = floorf(progress * 100) / 100;
       strs << percent;
       printf("%s\t%d\t%d\t%d\t%d\n", strs.str().c_str(),dltotal, dlnow, ultotal, ulnow);
       return 0;
    };

    curlpp::options::ProgressFunction progressBar(ProgressCallBack);
    request1.setOpt(new curlpp::options::Url(url1));
    request1.setOpt(new curlpp::options::Verbose(false));
    request1.setOpt(new curlpp::options::NoProgress(0));
    request1.setOpt(progressBar);

I am not entirely sure what part of my code would be relevant so here are the parts pertaining to the progress callback. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

虚拟世界 2024-12-16 19:26:37

这里有一些脏的划痕只是为了表达这个想法:

class CurlppProgress
{
  class Entry 
  {
  public:
    Entry( const CurlppProgress *owner );

    const CurlppProgress *owner;
    double dlTotal, dlNow, ulTotal, ulNow;

    void callback( double dltotal, double dlnow, double ultotal, double ulnow );
  };
  std::vector<Entry> entries;

  void print_progress() const;
  friend class Entry;
public:
  CurlppProgress();

  void AddEntry( curlpp::Easy *request );
};

CurlppProgress::Entry::Entry( const CurlppProgress *_owner )
  : owner( _owner )
  , dlNow()
  , dlTotal()
  , ulNow()
  , ulTotal()
{
}

void CurlppProgress::Entry::callback( double _dltotal, double _dlnow, double _ultotal, double _ulnow )
{
  dlNow = _dlnow;
  dlTotal = _dltotal;
  ulNow = _ulnow;
  ulTotal = _ultotal;
  owner->print_progress();
}

void CurlppProgress::AddEntry( curlpp::Easy *request )
{
  Entry newEntry( this );
  m_entries.push_back( newEntry );
  curlpp::types::ProgressFunctionFunctor progressFunctor(&m_entries.back(), &CurlppProgress::Entry::callback);
  request->setOpt(new curlpp::options::ProgressFunction(progressFunctor));

}

void CurlppProgress::print_progress() const
{
  double ulnow = 0.0;
  double ultotal = 0.0;
  double dlnow = 0.0;
  double dltotal = 0.0;
  for ( std::vector<Entry>::const_iterator i = entries.begin(), e = entries.end(); i != e; ++i )
  {
    ulnow += i->ulNow;
    ulTotal += i->ulTotal;
    dlnow += i->dlNow;
    dltotal += i->dlTotal;
  }

  // print progress here
}

但是你必须在使用之前修复它(所有权问题应该得到解决,向量的缓冲区重新分配会导致崩溃等)但我希望这个想法是清楚的。

Here some dirty scratch just to express the idea:

class CurlppProgress
{
  class Entry 
  {
  public:
    Entry( const CurlppProgress *owner );

    const CurlppProgress *owner;
    double dlTotal, dlNow, ulTotal, ulNow;

    void callback( double dltotal, double dlnow, double ultotal, double ulnow );
  };
  std::vector<Entry> entries;

  void print_progress() const;
  friend class Entry;
public:
  CurlppProgress();

  void AddEntry( curlpp::Easy *request );
};

CurlppProgress::Entry::Entry( const CurlppProgress *_owner )
  : owner( _owner )
  , dlNow()
  , dlTotal()
  , ulNow()
  , ulTotal()
{
}

void CurlppProgress::Entry::callback( double _dltotal, double _dlnow, double _ultotal, double _ulnow )
{
  dlNow = _dlnow;
  dlTotal = _dltotal;
  ulNow = _ulnow;
  ulTotal = _ultotal;
  owner->print_progress();
}

void CurlppProgress::AddEntry( curlpp::Easy *request )
{
  Entry newEntry( this );
  m_entries.push_back( newEntry );
  curlpp::types::ProgressFunctionFunctor progressFunctor(&m_entries.back(), &CurlppProgress::Entry::callback);
  request->setOpt(new curlpp::options::ProgressFunction(progressFunctor));

}

void CurlppProgress::print_progress() const
{
  double ulnow = 0.0;
  double ultotal = 0.0;
  double dlnow = 0.0;
  double dltotal = 0.0;
  for ( std::vector<Entry>::const_iterator i = entries.begin(), e = entries.end(); i != e; ++i )
  {
    ulnow += i->ulNow;
    ulTotal += i->ulTotal;
    dlnow += i->dlNow;
    dltotal += i->dlTotal;
  }

  // print progress here
}

But you have to fix it before using (ownership stuff should be resolved, and vector's buffer reallocation will cause crash and so on) but I hope the idea is clear.

夜未央樱花落 2024-12-16 19:26:37

免责声明:我的C++很生疏,而且我以前从未使用过curpp,所以下面的代码可能需要一些修改。

您的回调函数中需要的是能够区分两次下载的东西。由于curlpp 没有给你这个,你可能需要使用函子来代替。因此,对于您的进度回调,请创建一个类似于以下内容的类:

class ProgressCallback
{
public:
    ProgressCallback(int index) : downloadIndex(downloadIndex)
    {
    }

    double operator()(double dltotal, double dlnow, double ultotal, double ulnow)
    {
       double progress = (dlnow/dltotal) * 100;
       std::ostringstream strs;
       float percent = floorf(progress * 100) / 100;
       strs << percent;
       printf("%d: %s\t%d\t%d\t%d\t%d\n", downloadIndex,
              strs.str().c_str(),dltotal, dlnow, ultotal, ulnow);
       return 0;
    }

private:
    int downloadIndex;
};

现在,您应该能够像这样使用它:

ProgressCallback callback1(1);
curlpp::options::ProgressFunction progressBar(callback1);

当然,您需要考虑这些回调函子的生命周期。也许将它们留在堆栈上是一个坏主意。


编辑:似乎有一种更简单的方法可以做到这一点。在utilspp/functor.h中,定义了两个模板函数:make_functor()和BindFirst()。因此,您只需将 downloadIndex 参数添加到您的 ProgressCallback 即可:

double ProgressCallBack(int dlIdx,
                        double dltotal, double dlnow,
                        double ultotal, double ulnow);

并注册为:

curlpp::options::ProgressFunction
    progressBar(BindFirst(make_functor(ProgressCallback), 1));

Disclaimer: My C++ is rusty, and I have never used curlpp before, so the code below may need a bit of massaging.

What you need in your callback function is something that can differentiate between the two downloads. Since curlpp doesn't give you that, you probably need to use a functor instead. So, for your progress callback, make a class similar to:

class ProgressCallback
{
public:
    ProgressCallback(int index) : downloadIndex(downloadIndex)
    {
    }

    double operator()(double dltotal, double dlnow, double ultotal, double ulnow)
    {
       double progress = (dlnow/dltotal) * 100;
       std::ostringstream strs;
       float percent = floorf(progress * 100) / 100;
       strs << percent;
       printf("%d: %s\t%d\t%d\t%d\t%d\n", downloadIndex,
              strs.str().c_str(),dltotal, dlnow, ultotal, ulnow);
       return 0;
    }

private:
    int downloadIndex;
};

Now, you should be able to use this like:

ProgressCallback callback1(1);
curlpp::options::ProgressFunction progressBar(callback1);

Of course, you will need to think about the lifetime of these callback functors. Probably leaving them on stack would be a bad idea.


EDIT: There seems to be an easier way to do this. in utilspp/functor.h, there are two template functions defined: make_functor() and BindFirst(). So you could simply add a downloadIndex parameter to your ProgressCallback:

double ProgressCallBack(int dlIdx,
                        double dltotal, double dlnow,
                        double ultotal, double ulnow);

And register as:

curlpp::options::ProgressFunction
    progressBar(BindFirst(make_functor(ProgressCallback), 1));
掌心的温暖 2024-12-16 19:26:37

核心 libcurl 库允许您通过 CURLOPT_PROGRESSDATA 选项将用户定义的数据传递给进度回调,其中回调在 前面有一个额外的 void *clientp 参数。 code>double dltotal 参数:

typedef int (*curl_progress_callback)(void *clientp,
                                      double dltotal,
                                      double dlnow,
                                      double ultotal,
                                      double ulnow);

不过,查看 cURLpp 的最新源代码,它似乎并未公开对 CURLOPT_PROGRESSDATA 选项的访问。

The core libcurl library allows you to pass user-defined data to a progress callback via the CURLOPT_PROGRESSDATA option, where the callback has an additional void *clientp parameter in front of the double dltotal parameter:

typedef int (*curl_progress_callback)(void *clientp,
                                      double dltotal,
                                      double dlnow,
                                      double ultotal,
                                      double ulnow);

Looking at cURLpp's latest source code, it does not appear to expose access to the CURLOPT_PROGRESSDATA option, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文