以前一直看别人的帖子,这次自己也是通过别人的帖子解决了问题,质量略低,只是希望能够给别人一些方便,不要再走一些冤枉路。
一 废话不多说,首先需要进行的就是编译库,首先从sqlite开始,
Sqlite的配置:(参照http://blog.csdn.net/zmb2011/article/details/6401104)
1. 首先从SQLite的官网http://www.sqlite.org/download.html上下载两个文件包:sqlite-amalgamation-3070602.zip和sqlite-dll-win32-x86-3070600.zip
2. 解压amalgamation文件(里面包括四个文件,主要的是sqlite3.h)到D:/SQLite3/include,解压dll文件(sqlite3.def和sqlite3.dll文件)到D:/SQLite3/lib
3. 从VS2010的安装文件夹中的Visual Studio 10/VC/bin中找到LIB.exe和Link.exe,从Visual Studio 10中搜索得到mspdb100.dll文件,放入到D:/SQLite3/lib
4. 打开cmd窗口,转到D:/SQLite3/lib目录下,输入命令:LIB /DEF:sqlite3.def /machine:IX86,则会产生lib文件
5. 配置VS2010,VC++目录和库目录,分别包含include和lib文件夹
然后是libcurl的配置:
Libcurl的配置比较简单,只需要找到工程文件,将工程文件打开运行,就可以了,详细的中间有些小问题,都是可以解决的,如果遇到生成中缺少DLL的话,可以去网上下载一个,只要版本对就行,版本不对应该也没有问题。
废话不多说上代码:
可以下载到本地数据库的方法:
#include <stdio.h>
#include <curl/curl.h>
#include<string>
#include<sqlite3.h>
#include<iostream>
#include<fstream>
#include<vector>
#include<Windows.h>
using namespace std;
size_t write_data(FILE *ptr, size_t size, size_t count,FILE *stream)
{
FILE*fp=(FILE*)stream;
size_t return_size=fwrite(ptr,size,count,fp);
return return_size;
}
int main()
{
CURLcode res;
res = curl_global_init(CURL_GLOBAL_WIN32);
CURL *curl_handle;
curl_handle = curl_easy_init();
char *zErrMsg = 0;
if(res!=CURLE_OK)
{
std::cerr<<"initialize libcurl failed";
return-1;
}
if(curl_handle!=NULL)
{
FILE *fp = fopen("d:/ceshi/download.jpg","wb+");
res = curl_easy_setopt(curl_handle, CURLOPT_URL, "http://travel.paintedstork.com/blog/wp-content/uploads/2012/10/2013-calendar-images-1.jpg" );
res = curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
res = curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl_handle);
sqlite3 *db;
sqlite3_stmt *stat;
char *ffile;
int value= sqlite3_open("d:/ceshi/gtestpic.db", &db);
sqlite3_exec(db, "CREATE TABLE list (fliename varchar(128) UNIQUE, fzip blob);", 0, 0, &zErrMsg);
sqlite3_prepare(db, "insert into list values ('download',?);", -1, &stat, 0);
long filesize = 0;
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
fseek(fp, 0, SEEK_SET);
ffile=new char[filesize+1];
size_t sz=fread(ffile,sizeof(char),filesize+1,fp);
fclose(fp);
sqlite3_bind_blob(stat,1,ffile,filesize, NULL);
sqlite3_step(stat);
delete(ffile);
sqlite3_finalize(stat);
sqlite3_close(db);
fclose(fp) ;
curl_easy_cleanup(curl_handle);
curl_global_cleanup();
}
system("ERASE d:\\ceshi\\download.jpg");
return 0;
}
基本思路是这样的,先在本地建立文件,在通过libcurl的一系列函数进行加载,在这里libcurl的函数都是指定的,当然libcurl的函数有很多,我们不需要都理解,用到什么可以直接找,具体的每条函数有什么用我就不详细赘述了,大家可以参考这篇博文,http://blog.sina.com.cn/s/blog_40ce02d70100pt43.html讲的非常详细,可以有选择的参考,我重点要说的是第二种方法,本人系初入研究生一枚,水平有限,研究第二种方法迟迟没有进展,幸得师姐相助,半天搞定,部分代码参考网络,上代码
// scurl.cpp : 定义控制台应用程序的入口点。
//
#include <stdio.h>
#include <curl/curl.h>
#include<string>
#include<sqlite3.h>
#include<iostream>
#include<fstream>
#include<vector>
#include<Windows.h>
using namespace std;
//写入函数
static char errorBuffer[CURL_ERROR_SIZE];
static int writer(char*, size_t,size_t,string*);
static bool init(CURL *&, char *, string *);
static size_t get_count(char *url){
CURL *curl;
CURLcode res;
double filesize=0;
curl = curl_easy_init();
if (curl) {
res=curl_easy_setopt(curl, CURLOPT_URL, url);
res=curl_easy_setopt(curl, CURLOPT_NOBODY,1L);
res=curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
res=curl_easy_perform(curl);
if (res == CURLE_OK) {
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
} else {
filesize = -1;
}
return filesize;
}
}
int main()
{
char *zErrMsg = 0;
size_t fsize=0;
CURL *conn = NULL;
CURLcode code;
string buffer;
curl_global_init(CURL_GLOBAL_ALL);
char* url = "http://travel.paintedstork.com/blog/wp-content/uploads/2012/10/2013-calendar-images-1.jpg";
fsize=get_count(url);
if (!init(conn,url,&buffer))
{
fprintf(stderr,"Connection initializion failed\n");
exit(EXIT_FAILURE);
}
code = curl_easy_perform(conn);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to get '%s' [%s]\n", url, errorBuffer);
exit(EXIT_FAILURE);
}
curl_easy_cleanup(conn);
printf("%s\n",buffer.c_str());
FILE *file;
file = fopen("d:/resultlib.jpg", "wb");
if(file != NULL)
{
size_t ret = fwrite((void*)buffer.c_str(), sizeof(char), fsize,file);
fclose(file);
}
//读入数据库
sqlite3 *db;
sqlite3_stmt *stat;
int value= sqlite3_open("d:/gtestpic.db", &db);
sqlite3_exec(db, "CREATE TABLE list (fliename varchar(128) UNIQUE, fzip blob);", 0, 0, &zErrMsg);
sqlite3_prepare(db, "insert into list values ('download3',?2);", -1, &stat, 0);
sqlite3_bind_blob(stat,2,(void*)buffer.c_str(),fsize, SQLITE_STATIC);
sqlite3_step(stat);
//选取该条数据
sqlite3_prepare(db, "select*from list;", -1, &stat, 0);
sqlite3_step(stat);
//得到记录中的BLOB字段
const void * test = sqlite3_column_blob(stat, 1);
//得到字段中数据的长度
int size = sqlite3_column_bytes(stat, 1);
FILE *fp2;
fp2 = fopen("d:/outfile2.jpg", "wb");
if(fp2 != NULL)
{
size_t ret = fwrite(test, sizeof(char), size, fp2);
fclose(fp2);
}
//释放资源
//delete[]buffer;
sqlite3_finalize(stat);
sqlite3_close(db);
//}
//释放资源
//curl_easy_cleanup(curl_handle);
curl_global_cleanup();
return 0;
}
static bool init(CURL *&conn, char *url, string *p_buffer)
{
CURLcode code;
conn = curl_easy_init();
if (conn == NULL)
{
fprintf(stderr,"Failed to create CURL connection\n");
exit(EXIT_FAILURE);
}
code = curl_easy_setopt(conn,CURLOPT_ERRORBUFFER,errorBuffer);
if (code!=CURLE_OK)
{
fprintf(stderr,"Failed to set error buffer[%d]\n",code);
return false;
}
code = curl_easy_setopt(conn,CURLOPT_URL,url);
if (code!=CURLE_OK)
{
fprintf(stderr,"Failed to set URL [%s]\n",errorBuffer);
return false;
}
code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
return false;
}
code = curl_easy_setopt(conn,CURLOPT_WRITEFUNCTION,writer);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
return false;
}
code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, p_buffer);
if (code != CURLE_OK)
{
fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
return false;
}
return true;
}
static int writer(char* data,size_t size,size_t nmemb, string *writerData)
{
unsigned long sizes = size*nmemb;
if(writerData == NULL)
return 0;
writerData->append(data, sizes);
return sizes;
}
大致思路是这样的,利用函数get_count()获取目标文件的大小,在新开辟内存,大小为目标文件的大小,这样利用libcurl函数将目标文件存入字符数组,存入后就可以导入数据库了,最后一段代码是用来进行读数据读取的。
在过程中遇到了不少的问题,一开始并不知道libcurl中有可以用来读取目标文件的大小的函数,但是后来发现了函数CURLINFO_CONTENT_LENGTH_DOWNLOAD才找打了解决问题的正确思路,另外在write_data中开始时用的是memcpy函数,但是后来证明这个函数在这方面有问题,具体问题现在也没有搞清楚,改为memmove后,问题还是没有实质性的进展,后来被师姐将数据流改为string格式,使用append函数,才解决了问题,有时候觉得自己一个人解决了很就解决不了的问题,别人只要稍微指点就解决了,不由的觉得自己太水了,以后还要继续努力。