如何读取图像文件并将其存储在c ++的内存(std :: string)中?

时间:2012-03-08 02:27:28

标签: c++ string image file binary

我今天大部分时间都在线研究,但找不到答案,所以我转向stackoverflow提出一些建议。

基本上,我有一个c ++库,它使用curl来执行PUT方法来上传图像文件。现在这个库为数据采用std :: string。我的本地磁盘上有图像文件(如jpg,gif,png)。

我不关心文件的内容(因为,除了将其传递给此库以用于PUT方法之外,我不做任何事情)。我怎样才能读取图像文件并将其存储在std :: string中?如果文件内容包含NULL终结符怎么办?

我尝试添加一些我尝试过的代码,但我是新来的,我不知道如何以正确的格式粘贴我的代码。任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:4)

我能想到的最简单的方法。以二进制模式打开文件,然后将整个内容读入stringstream

std::ifstream fin("foo.png", std::ios::in | std::ios::binary);
std::ostringstream oss;
oss << fin.rdbuf();
std::string data(oss.str());

答案 1 :(得分:3)

std::ifstream fin("foo.png", std::ios::binary);
std::string data;
data.reserve(1000000);
std::copy(std::istreambuf_iterator<char>(fin),
          std::istreambuf_iterator<char>(),
          std::back_inserter(data));

您可以使用此类代码将图像文件读取到std::string。将reserve方法的参数调整为大于文件大小的99%。使用ifstreamstring正确处理零字节(您调用NULL终止符)。


我找到了一个很好的article,其中比较了几种二进制文件加载方法。这是该文章中最快的方法:

std::ifstream fin("foo.png", std::ios::binary);
fin.seekg(0, std::ios::end);
std::string data;
data.resize(fin.tellg());
fin.seekg(0, std::ios::beg);
fin.read(&data[0], data.size());

这是最短的一个:

std::ifstream fin("foo.png", std::ios::binary);
std::string data((std::istreambuf_iterator<char>(fin)),
                 std::istreambuf_iterator<char>());

<强>更新

这样的东西可以用来提供回调函数(我没有测试它):

std::ifstream fin("foo.png", std::ios::binary);
fin.seekg(0, std::ios::end);
...
curl_easy_setopt(m_ctx, CURLOPT_INFILESIZE,    fin.tellg());
curl_easy_setopt(m_ctx, CURLOPT_READDATA,      (void *)&fin);
fin.seekg(0, std::ios::beg);
...
static size_t put_callback(void *ptr, size_t size, size_t nmemb, void *data){
  std::ifstream* in = static_cast<std::ifstream*>(data);
  if(in->eof()) return 0;
  in->read((char *)ptr, size*nmemb);
  return in->gcount();
}

答案 2 :(得分:2)

这就是库如何进行PUT调用,其中'data'是作为文件内容传入的数据

stringstream data_stream.str(data.c_str());
curl_easy_setopt(m_ctx, CURLOPT_UPLOAD,        1L);
curl_easy_setopt(m_ctx, CURLOPT_PUT,           1L);
curl_easy_setopt(m_ctx, CURLOPT_INFILESIZE,    data.length());
curl_easy_setopt(m_ctx, CURLOPT_READFUNCTION,  put_callback);
curl_easy_setopt(m_ctx, CURLOPT_READDATA,      (void *)&data_stream);
curl_easy_setopt(m_ctx, CURLOPT_WRITEFUNCTION, get_callback);
curl_easy_setopt(m_ctx, CURLOPT_WRITEDATA,     (void *)&m_request_response);

这里是curlopt_readfunction的回调函数

static size_t put_callback(void *ptr, size_t size, size_t nmemb, void *data){

  stringstream *output_stream;
  int          retval;

  output_stream = (stringstream *) data;

  if(output_stream->eof()) return 0;

  retval = min(size*nmemb,output_stream->str().size());
  output_stream->read((char *)ptr, retval);

  //return the number of bytes processed 
  return retval;
}