基于curl实现文件下载
curl第三方库的安装
sudo apt-get install libcurl4-openssl-dev
实现文件下载思路
- 使用curl发送请求获取需要下载的文件的大小
- 再次使用curl下载文件
代码
#include <cstring>
#include <iostream>
#include <curl/curl.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/mman.h>
#include <unistd.h>
using namespace std;
struct fileInfo
{
char *fileptr;
int offset;
/* data */
};
size_t writeFunc(void *ptr, size_t size, size_t memb, void *userdata)
{
fileInfo *info = (fileInfo *)userdata;
// printf("aaaaaa");
memcpy(info->fileptr + info->offset, ptr, size * memb);
info->offset += size * memb;
return size * memb;
}
double getDownloadFileLength(const char* url){
double length;
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_HEADER, 1);
curl_easy_setopt(curl, CURLOPT_NOBODY, 1);
CURLcode res = curl_easy_perform(curl);
if (res == CURLE_OK)
{
curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &length);
}else{
length = -1;
}
curl_easy_cleanup(curl);
return length;
}
int download(const char *url, const char *filename)
{
long length = getDownloadFileLength(url);
printf("file lenght:%ld\n", length);
int fd = open(filename,O_RDWR | O_CREAT | S_IWUSR);
if(fd==-1){
return -1;
}
if(-1==lseek(fd, length-1, SEEK_SET)){
perror("lseek");
close(fd);
return -1;
}
if(1!=write(fd,"",1)){
perror("write");
close(fd);
return -1;
}
char* fileptr = (char*)mmap(NULL, length, PROT_READ | PROT_WRITE,MAP_SHARED, fd, 0);
if(fileptr==MAP_FAILED){
perror("mmap");
close(fd);
return -1;
}
fileInfo *info = (fileInfo*)malloc(sizeof(fileInfo));
if(info==NULL){
munmap(fileptr, length);
close(fd);
return -1;
}
info->fileptr = fileptr;
info->offset = 0;
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunc);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,info);
CURLcode res = curl_easy_perform(curl);
if (res != CURLE_OK)
{
printf("res %d\n", res);
}
curl_easy_cleanup(curl);
free(info);
munmap(fileptr, length);
close(fd);
return 0;
}
int main()
{
cout << "hello" << endl;
download("https://releases.ubuntu.com/22.04/ubuntu-22.04.4-live-server-amd64.iso.zsync","ubuntu.zsync");
return 0;
}