libaria2:C++库接口到aria2¶
Warning
API尚未固定。它将在开发过程中被更改。
libaria2是一个C++库,提供aria2的核心功能。该库处理所有网络和下载相关的事务, 所以它的使用现在非常直接。查看以下教程部分了解如何使用API。
教程¶
本节是逐步指导创建一个使用libaria2下载文件的程序。完整的源代码位于 examples 目录下的 libaria2ex.cc。
libaria2ex 程序接受一个或多个URI,并且并行下载每个 文件。使用方式如下:
使用方式: libaria2ex URI [URI…]
在当前目录下并行下载给定的URI。
源代码使用C++11特性,因此需要支持C++11的编译器。 GCC 4.7在这里工作良好。
好的,让我们来看看源代码。首先,包含aria2.h头文件:
#include <aria2/aria2.h>
跳转到 main() 函数。在检查命令行
参数后,我们初始化libaria2:
aria2::libraryInit();
并创建aria2会话对象:
aria2::Session* session;
// 创建默认配置。libaria2处理信号
// 处理。
aria2::SessionConfig config;
// 添加事件回调
config.downloadEventCallback = downloadEventCallback;
session = aria2::sessionNew(aria2::KeyVals(), config);
Session session 是一个aria2会话对象。您需要这个
对象贯穿整个下载过程。请记住,由于在aria2代码库中大量使用静态对象,每个进程只允许一个:type:Session`对象。:type:`Session`对象不适用于从多个线程并发访问。它必须一次从一个线程使用。一般来说,libaria2并不是完全线程安全的。:type:`SessionConfig config 保存会话对象的配置。构造函数使用默认值初始化它。在此设置中,SessionConfig::keepRunning 是
false 表示当所有下载都处理完毕时 run() 返回,就像没有启用RPC的aria2c工具一样。并且 SessionConfig::useSignalHandler 是 true,意味着libaria2将设置信号处理器并捕获某些信号以优雅地停止下载过程。我们还设置了事件处理回调函数 downloadEventCallback。当发生事件时,比如下载开始、完成等,它将被调用。在这个示例程序中,我们处理了两个事件:下载完成和错误。对于每个事件,我们打印下载的GID和其他几个
信息:
int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
const aria2::A2Gid& gid, void* userData)
{
switch(event) {
case aria2::EVENT_ON_DOWNLOAD_COMPLETE:
std::cerr << "COMPLETE";
break;
case aria2::EVENT_ON_DOWNLOAD_ERROR:
std::cerr << "ERROR";
break;
default:
return 0;
}
std::cerr << " [" << aria2::gidToHex(gid) << "] ";
...
}
userData 对象由
SessionConfig::userData 指定。在这个示例中,我们没有指定
它,所以它是 nullptr。
sessionNew() 的第一个参数是 aria2::KeyVals()。
这个类型在API中用于指定键/值对的向量,大多表示aria2选项。例如,指定选项
file-allocation 为 none:
aria2::KeyVals options;
options.push_back(std::pair<std::string, std::string> ("file-allocation", "none"));
sessionNew() 的第一个参数类似于aria2c程序的
命令行参数。在示例程序中,我们没有提供任何选项,所以只需传递空向量。
在创建会话对象之后,让我们添加命令行中给出的下载:
// 将下载项添加到会话中
for(int i = 1; i < argc; ++i) {
std::vector<std::string> uris = {argv[i]};
aria2::KeyVals options;
rv = aria2::addUri(session, nullptr, uris, options);
if(rv < 0) {
std::cerr << "添加下载失败 " << uris[0] << std::endl;
}
}
我们迭代命令行参数并将每个参数作为一个单独的
下载添加。addUri() 可以接受一个或多个URI来下载
多个源,就像aria2c一样,但在这个例子中,我们只
给出了一个URI。我们没有为下载提供特定的选项,
所以传递空向量作为选项。addUri()
的第二个参数接受一个指向 A2Gid 的指针。如果它不是
NULL,函数会将新下载的GID分配给它。在
这个示例代码中,我们对它不感兴趣,所以只需传递
nullptr。
到目前为止,我们已经设置好了一切。所以让我们开始下载。为了
执行下载,反复调用 run() 直到它返回
不是 1 的值:
for(;;) {
rv = aria2::run(session, aria2::RUN_ONCE);
if(rv != 1) {
break;
}
...
}
这里,我们用 RUN_ONCE 调用 run()。这意味着
run() 在一次事件轮询及其动作处理
或轮询超时(大约1秒)后返回。如果 run()
返回 1,意味着下载正在进行中,应用程序必须再次调用它。如果它返回 0,那么没有下载
剩余(或它被信号处理器或 shutdown() 停止)。
如果函数捕获错误,它返回 -1。使用 RUN_ONCE 的好处是应用程序可以在 run() 返回时使用libaria2 API。在示例程序中,我们每隔不少于500毫秒打印一次
下载进度:
// 每500ms打印一次进度信息
if(count >= 500) {
start = now;
aria2::GlobalStat gstat = aria2::getGlobalStat(session);
std::cerr << "整体 #活跃:" << gstat.numActive
<< " #等待:" << gstat.numWaiting
<< " D:" << gstat.downloadSpeed/1024 << "KiB/s"
<< " U:"<< gstat.uploadSpeed/1024 << "KiB/s " << std::endl;
std::vector<aria2::A2Gid> gids = aria2::getActiveDownload(session);
for(const auto& gid : gids) {
aria2::DownloadHandle* dh = aria2::getDownloadHandle(session, gid);
if(dh) {
std::cerr << " [" << aria2::gidToHex(gid) << "] "
<< dh->getCompletedLength() << "/"
<< dh->getTotalLength() << "("
<< (dh->getTotalLength() > 0 ?
(100*dh->getCompletedLength()/dh->getTotalLength())
: 0) << "%)"
<< " D:"
<< dh->getDownloadSpeed()/1024 << "KiB/s, U:"
<< dh->getUploadSpeed()/1024 << "KiB/s"
<< std::endl;
aria2::deleteDownloadHandle(dh);
}
}
}
我们首先调用 getGlobalStat() 函数来获取下载的全局
统计信息。然后,调用 getActiveDownload()
函数来获取活动下载的GID向量。对于每个GID,我们
使用 getDownloadHandle() 函数检索 DownloadHandle 对象并获取详细信息。
请不要忘记在使用后和下一次调用 run() 之前删除 DownloadHandle。请记住 DownloadHandle 对象的生命周期是在下一次调用 run() 之前。
循环结束后,调用 sessionFinal()
函数完成下载,并调用 libraryDeinit() 释放库的资源:
rv = aria2::sessionFinal(session);
aria2::libraryDeinit();
return rv;
调用 sessionFinal() 很重要,因为它执行下载后的操作,包括保存会话和销毁会话对象。因此,如果不调用此函数,将导致下载进度丢失和内存泄漏。sessionFinal() 返回在 退出状态 中定义的代码。aria2c 程序也返回相同的值作为退出状态,所以在这个小示例程序中也做同样的操作。
另请参见 libaria2wx.cc,它使用 wx GUI 组件作为用户界面,并使用后台线程运行下载。
API 参考¶
要使用 API 函数,请包含 aria2/aria2.h:
#include <aria2/aria2.h>
所有枚举、类型和函数都在 aria2 命名空间下。要链接 libaria2,请使用链接器标志 -laria2。