Индикатор выполнения консоли C ++ libcurl

Я хочу, чтобы индикатор выполнения отображался в окне консоли во время загрузки файла. Мой код таков: Загрузить файл с помощью libcurl на C / C ++.

Как получить индикатор выполнения в libcurl?


person Community    schedule 28.10.2009    source источник


Ответы (3)


Ваш счетчик.

#include <math.h>

int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, 
                    double TotalToUpload, double NowUploaded)
{
    // ensure that the file to be downloaded is not empty
    // because that would cause a division by zero error later on
    if (TotalToDownload <= 0.0)) {
        return 0;
    }

    // how wide you want the progress meter to be
    int totaldotz=40;
    double fractiondownloaded = NowDownloaded / TotalToDownload;
    // part of the progressmeter that's already "full"
    int dotz = (int) round(fractiondownloaded * totaldotz);

    // create the "meter"
    int ii=0;
    printf("%3.0f%% [",fractiondownloaded*100);
    // part  that's full already
    for ( ; ii < dotz;ii++) {
        printf("=");
    }
    // remaining part (spaces)
    for ( ; ii < totaldotz;ii++) {
        printf(" ");
    }
    // and back to line begin - do not forget the fflush to avoid output buffering problems!
    printf("]\r");
    fflush(stdout);
    // if you don't return 0, the transfer will be aborted - see the documentation
    return 0; 
}
person fvu    schedule 28.10.2009
comment
Большое тебе спасибо! Мне просто нужно было включить math.h, и он отлично работает. - person ; 28.10.2009
comment
@fvu Привет Здесь я реализовал способ, который вы предложили, но я не получил никакого значения в этой функции progress_func. - person user1089679; 16.05.2012
comment
Красиво, я адаптировал это к C, работает очень, очень хорошо! - person workdreamer; 13.05.2015
comment
@workdreamer Рад, что вам понравилось, но я немного озадачен, код выше - C;) - person fvu; 13.05.2015
comment
@workdreamer спасибо за редактирование! Если вы используете php, также просмотрите phpclimate простой способ сделайте еще более шикарный бар :) - person fvu; 14.05.2015
comment
Библиотека интересная. возможно я воспользуюсь им позже. теперь я использую ваш код :) - person workdreamer; 14.05.2015

Из документации по curl

CURLOPT_PROGRESSFUNCTION

Указатель на функцию, который должен соответствовать прототипу curl_progress_callback, найденному в. Эта функция вызывается libcurl вместо ее внутреннего эквивалента с частым интервалом во время работы (примерно один раз в секунду) независимо от того, передаются данные или нет. Неизвестные / неиспользованные значения аргументов, переданные в обратный вызов, будут установлены на ноль (например, если вы загружаете только данные, размер загрузки останется 0). Возврат ненулевого значения из этого обратного вызова приведет к тому, что libcurl прервет передачу и вернет CURLE_ABORTED_BY_CALLBACK.

So:

Вы предоставляете функцию, которая выглядит так

int progress_func(void* ptr, double TotalToDownload, double NowDownloaded, double TotalToUpload, double NowUploaded)
{
    // It's here you will write the code for the progress message or bar
}

И несколько дополнительных опций после существующих опций

curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);  // already there
// Internal CURL progressmeter must be disabled if we provide our own callback
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
// Install the callback function
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_func); 

Это все что нужно сделать

person fvu    schedule 28.10.2009
comment
Моя проблема в том, что я не могу сделать рабочий код для индикатора выполнения. - person ; 28.10.2009
comment
@marios if i put curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); // Установить функцию обратного вызова curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_func);, тогда загрузка не удалась - person user1089679; 16.05.2012
comment
@ user1089679 убедитесь, что вы возвращаете 0 в обратном вызове - person André Morujão; 11.09.2012

Как удачный индикатор выполнения

#include <iostream>
#include <fstream>
#include <include/curl/curl.h>//Or #include <curl/curl.h>
#include <windows.h>
#include <math.h>

using namespace std;

int nb_bar;
double last_progress, progress_bar_adv;

HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

int progress_bar (void *bar, double t, double d)
{
    if(last_progress != round(d/t*100))
    {
      nb_bar = 25;
      progress_bar_adv = round(d/t*nb_bar);

      cout<<"\r ";
      SetConsoleTextAttribute(hConsole, 160);
      cout<<" Progress : [ ";

      if(round(d/t*100) < 10)
      { cout<<"0"<<round(d/t*100)<<" %]"; }
      else
      { cout<<round(d/t*100)<<" %] "; }

      SetConsoleTextAttribute(hConsole, 15);
      cout<<" [";
      SetConsoleTextAttribute(hConsole, 10);
      for(int i = 0 ; i <= progress_bar_adv ; i++)
      { cout<<"#"; }
      SetConsoleTextAttribute(hConsole, 15);
      for(int i = 0 ; i < nb_bar - progress_bar_adv; i++)
      { cout<<"."; }

      cout<<"]";
      last_progress = round(d/t*100);
    }
  return 0;
}


int main()
{
  CURL *curl_download;
  FILE *fp;
  CURLcode res;
  string url = "http://www.gecif.net/articles/mathematiques/pi/pi_1_million.txt", output_file = "pi.txt";

  curl_download = curl_easy_init();

  if (curl_download)
  {
      //SetConsoleTextAttribute(hConsole, 11);
      fp = fopen(output_file.c_str(),"wb");

      curl_easy_setopt(curl_download, CURLOPT_URL, url.c_str());
      curl_easy_setopt(curl_download, CURLOPT_WRITEFUNCTION, NULL);
      curl_easy_setopt(curl_download, CURLOPT_WRITEDATA, fp);
      curl_easy_setopt(curl_download, CURLOPT_NOPROGRESS, FALSE);
      //progress_bar : the fonction for the progress bar
      curl_easy_setopt(curl_download, CURLOPT_PROGRESSFUNCTION, progress_bar);

      //Text color :   SetConsoleTextAttribute(hConsole, nb_color);
      SetConsoleTextAttribute(hConsole, 11);
      cout<<" Start download"<<endl<<endl;

      res = curl_easy_perform(curl_download);

      fclose(fp);
      if(res == CURLE_OK)
      {
        SetConsoleTextAttribute(hConsole, 10);
        cout<<endl<<endl<<" The file was download with succes"<<endl;
      }
      else
      {
        SetConsoleTextAttribute(hConsole, 4);
        cout<<endl<<endl<<" Error"<<endl;
      }
      curl_easy_cleanup(curl_download);
  }
  SetConsoleTextAttribute(hConsole, 11);
  return 0;
}
person Pmimo    schedule 09.01.2018