其他语言都比较方便,使用http上传。但是C++这样就差点,不过还好,Linux下有个curl的命令行工具,这是一个开源项目,底下有个子项目是libcurl,curl就是调用这个API实现的一系列ftp,http等上传下载的功能,这个库功能还是挺多的。支持的协议也多。这样就可以利用这个库来实现http上传和下载了。

当然这个库的API有两种接口,一种是esay的-------同步阻塞模式。另一种是Multi的,我没研究它,以下用的都是easy的接口,来写的样例代码。

不过在学这个库的接口之前,最好先了解下http,特别是GET和POST方法的区别,这两个方法前者涉及到对URL的查询,后者涉及到对URL的改写。当然GET和POST都可以向server传输数据。并不能根据它们的名字直接理解,详情请看http协议吧。我找了两个不错的博客连接,来理解http相关的内容,非常不错,写得很好:

http://www.cnblogs.com/devil-91/archive/2012/05/11/2495266.html

http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html

文件上传类:

H文件:

#ifndef QCURL_SENDER_H
#define QCURL_SENDER_H #include <string> #include <curl/curl.h> class CurlSender{ public:
CurlSender();
~CurlSender(); bool isValid() const;
void setUrl(const std::string& url);
bool send(const std::string &file); private:
std::string getFileNameFromPath(const std::string& path); private:
CURL* m_hCurl;
std::string m_url;
bool m_isValid;
}; #endif

  .cpp文件

#include "QCurlSender.h"

CurlSender::CurlSender():
m_hCurl(nullptr), m_isValid(false)
{
curl_global_init(CURL_GLOBAL_ALL);
m_hCurl = curl_easy_init(); if (m_hCurl)
{
m_isValid = true;
}
} CurlSender::~CurlSender()
{
if (m_hCurl)
{
curl_easy_cleanup(m_hCurl);
} curl_global_cleanup();
} bool CurlSender::isValid() const
{
return m_isValid;
} void CurlSender::setUrl(const std::string& url)
{
m_url = url;
} bool CurlSender::send(const std::string &file)
{ curl_slist* pOptionList = NULL;
pOptionList = curl_slist_append(pOptionList, "Expect:");
curl_easy_setopt(m_hCurl, CURLOPT_HTTPHEADER, pOptionList); curl_httppost* pFormPost = NULL;
curl_httppost* pLastElem = NULL; //上传文件,指定本地文件完整路径
curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, file.c_str(), CURLFORM_CONTENTTYPE,
"application/octet-stream", CURLFORM_END); curl_formadd(&pFormPost, &pLastElem,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, getFileNameFromPath(file).c_str(),
CURLFORM_END);
//不加一个结束的hfs服务端无法写入文件,一般不存在这种问题,这里加入只是为了测试.
curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "end", CURLFORM_COPYCONTENTS, "end", CURLFORM_END);
curl_easy_setopt(m_hCurl, CURLOPT_HTTPPOST, pFormPost);
curl_easy_setopt(m_hCurl, CURLOPT_URL, m_url.c_str()); CURLcode res = curl_easy_perform(m_hCurl);
if (res != CURLE_OK)
{
return false;
} curl_formfree(pFormPost); return true;
} std::string CurlSender::getFileNameFromPath(const std::string& path)
{ return path.substr(path.find_last_of("/\\") + 1); }

  

http下载类:

H文件:

 #ifndef TASK_HTTP_RECVER_H
#define TASK_HTTP_RECVER_H #include <curl/curl.h>
#include <string>
#include <cstdio> class HttpRecver { public:
HttpRecver();
~HttpRecver(); bool isValid() const;
void setUrl(const std::string& url);
void setSavePath(const std::string &path); private:
bool recv();
//下载回调函数
static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam);
std::string getFileNameFromPath(const std::string& path); private:
FILE *m_fp;
CURL* m_hCurl;
std::string m_url;
std::string m_savePath;
std::string m_filename;
bool m_isValid;
bool m_bReady; }; #endif

cpp文件:

 #include "TaskHttpRecver.h"

 HttpRecver::HttpRecver() :
m_isValid(false), m_hCurl(nullptr), m_fp(nullptr)
{ LOG_(LOGID_DEBUG, LOG_F("Entry HttpRecver()")); curl_global_init(CURL_GLOBAL_ALL);
m_hCurl = curl_easy_init(); if (m_hCurl)
{
m_isValid = true;
} LOG_(LOGID_DEBUG, LOG_F("Entry HttpRecver()"));
} HttpRecver::~HttpRecver()
{
LOG_(LOGID_DEBUG, LOG_F("Entry ~HttpRecver()")); if (m_hCurl)
{
curl_easy_cleanup(m_hCurl);
} curl_global_cleanup(); LOG_(LOGID_DEBUG, LOG_F("Leave ~HttpRecver()"));
} bool HttpRecver::isValid() const
{
return m_isValid;
} void HttpRecver::setUrl(const std::string& url)
{
m_url = url;
m_filename = getFileNameFromPath(m_url);
} void HttpRecver::setSavePath(const std::string &path)
{
m_savePath = path;
} std::string HttpRecver::getFileNameFromPath(const std::string& path)
{
return path.substr(path.find_last_of("/\\") + );
} bool HttpRecver::recv()
{
curl_easy_setopt(m_hCurl, CURLOPT_URL, m_url.c_str()); std::string filePath = m_savePath + m_filename; m_fp = fopen(filePath.c_str(), "wb"); if (!m_fp)
{
return false;
} //设置接收数据的回调
curl_easy_setopt(m_hCurl, CURLOPT_WRITEFUNCTION, DownloadCallback);
curl_easy_setopt(m_hCurl, CURLOPT_WRITEDATA, m_fp);
curl_easy_setopt(m_hCurl, CURLOPT_MAXREDIRS, );
curl_easy_setopt(m_hCurl, CURLOPT_FOLLOWLOCATION, ); CURLcode retcCode = curl_easy_perform(m_hCurl); if (retcCode != CURLE_OK)
{ fclose(m_fp);
m_fp = nullptr;
return false;
} fclose(m_fp);
m_fp = nullptr; return true;
} size_t HttpRecver::DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam)
{
FILE* fp = (FILE*)pParam;
size_t nWrite = fwrite(pBuffer, nSize, nMemByte, fp); return nWrite;
}

references:

http://www.cnblogs.com/cswuyg/archive/2013/07/11/3185164.html

http://www.cnblogs.com/lidabo/p/4159574.html

http://blog.csdn.net/breaksoftware/article/details/45874197

http://stackoverflow.com/questions/8520560/get-a-file-name-from-a-path

http://blog.csdn.net/mfcing/article/details/43051865

http://blog.csdn.net/infoworld/article/details/46646933

利用http实现文件的上传和下载的更多相关文章

  1. iOS开发中文件的上传和下载功能的基本实现-备用

    感谢大神分享 这篇文章主要介绍了iOS开发中文件的上传和下载功能的基本实现,并且下载方面讲到了大文件的多线程断点下载,需要的朋友可以参考下 文件的上传 说明:文件上传使用的时POST请求,通常把要上传 ...

  2. java web(四):request、response一些用法和文件的上传和下载

    上一篇讲了ServletContent.ServletCOnfig.HTTPSession.request.response几个对象的生命周期.作用范围和一些用法.今天通过一个小项目运用这些知识.简单 ...

  3. java实现文件的上传和下载

    1. servlet 如何实现文件的上传和下载? 1.1上传文件 参考自:http://blog.csdn.net/hzc543806053/article/details/7524491 通过前台选 ...

  4. 使用Loadrunner进行文件的上传和下载

    最近使用loadrunner中需要录制文件的上传和下载,上传功能模块利用录制可以直接实现,下载无法实现,在网上找到了一段代码,自己动手试验了下,发现没有用 辛苦找到的,还是记录下吧 (1)LoadRu ...

  5. Java中文件的上传与下载

    文件的上传与下载主要用到两种方法: 1.方法一:commons-fileupload.jar  commons-io.jar apache的commons-fileupload实现文件上传,下载 [u ...

  6. Javaweb之文件的上传与下载

    Javaweb之文件的上传与下载 一.基于表单的文件上传 如果在表单中使用表单元素 <input type=“file” />,浏览器在解析表单时,会自动生成一个输入框和一个按钮,输入框可 ...

  7. .net web开发——文件的上传和下载

    以ASP.NET Core WebAPI 作后端 API ,用 Vue 构建前端页面,用 Axios 从前端访问后端 API ,包括文件的上传和下载. 准备文件上传的API #region 文件上传  ...

  8. java实现ftp文件的上传与下载

    最近在做ftp文件的上传与下载,基于此,整理了一下资料.本来想采用java自带的方法,可是看了一下jdk1.6与1.7的实现方法有点区别,于是采用了Apache下的框架实现的... 1.首先引用3个包 ...

  9. 在SpringMVC框架下实现文件的 上传和 下载

    在eclipse中的javaEE环境下:导入必要的架包 web.xml的配置文件: <?xml version="1.0" encoding="UTF-8" ...

随机推荐

  1. 有限状态机FSM(自动售报机Verilog实现)

    有限状态机FSM(自动售报机Verilog实现) FSM 状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法. 状态机有两大类:Mealy型和Moore型. Moore型状态机的输出只与当前状态有 ...

  2. Java程序员可能犯的3个常见SQL错误

    概述:Java程序员不仅要具备扎实的Java编程能力,在日常的工作当中往往还要涉及到其他语言的基础知识,尤其是SQL.那么哪些常见的SQL错误是程序员们容易犯的呢?让我们一起来看看吧! 你可能看到Ja ...

  3. ngnix 一 入门指南

    翻译自:ngnix--Beginner Guide ##ngnix入门指南 本指南给出了nginx的基本介绍,并介绍了可以使用它的完成一些简单任务. 它假定nginx已经安装在读者的机器上. 如果不是 ...

  4. 数据迁移sql

    1.把数据库test中的表Table1中的数据插入到数据库test2中的表Table2:insert into test2.Table2(a,c,d) select a,c,5 from test.T ...

  5. ios AFNetworking 有用篇

    在寻常开发中,af是个非常好用的东西.非常喜欢.可是网上的af找了好多都不太全面,不有用.所以我今天做了一个demo.有上传下载的. 比較有用.希望大家可以用到. 去我github下载demo git ...

  6. 线程在WPF中的使用

    项目中可能会有这样的需求,一直获取新的某个数据信息,但仍不影响其他的操作功能,这时就用到了线程,获取新数据放到线程中操作,对其他操作不产生影响,下面就以随机获取数组中项为例解说WPF中使用线程这一实例 ...

  7. spring07 JDBC

    1.创建对应的数据库 2.在MyEclipse中创建项目  引入需要的jar包 3.创建数据访问层 public interface StudentDao { //新增学生 int addStuden ...

  8. 封装函数--->切换,添加,删除class

    var obj={}; obj.className='a b c d active'; //切换class function toggle(obj,className) { var str=obj.c ...

  9. 【转】Android开源项目 分类 便于查看

    之前转载了一个开源项目的文章,发现那些都是没有系统的总结,这里又转载一篇有系统总结的文章. Android开源项目系列汇总已完成,包括: Android开源项目第一篇——个性化控件(View)篇 An ...

  10. spring aop原理分析

    持续更新... aop跟java代理模式有关. java.lang.reflect.Proxy java.lang.reflect.InvocationHandler 工厂模式用到java反射. ao ...