2012-03-08 16 views
6

Bugün çoğunu çevrimiçi araştırdım, ancak cevabı bulamadım bu yüzden bazı öneriler için stackoverflow'a dönüyorum. Temel olarak, bir görüntü dosyasını yüklemek için PUT yöntemini gerçekleştirmek için curl kullanan bir C++ kitaplığına sahibim. şimdi bu kütüphane veri için bir std :: dize alır. yerel diskimde görüntü dosyaları (jpg, gif, png gibi) var.Görüntü dosyalarını okumak ve C++ 'da belleğe (std :: string) nasıl kaydeder?

Dosyanın içeriği ile ilgili bir şey umurumda değil (PUT yöntemi için bu kütüphaneye aktarılmasının yanı sıra bir şey yapmıyorum). görüntü dosyalarını nasıl okuyabilirim ve std :: string dosyasında saklayabilirim? Dosya içeriği NULL terminatör içeriyorsa ne olur?

Denediğim kodlardan bazılarını eklemeyi denedim, ancak burada yeniyim ve kodumu doğru biçimde buraya nasıl yazacağımı bilmiyorum. herhangi bir yardım takdir edilecektir.

+0

için geri arama frunction bu olduğunu, sadece her şeyi 4 boşlukla gir. Veya kodunuzu yapıştırın, seçin, ardından şu şekilde görünen düğmeye basın: '{}'. Metni, küçük şeylerle çevreleyerek metin içine de yerleştirebilirsiniz. Bence geri-keneler olarak adlandırılıyorlar. Şimdiye kadar kullandığım her klavyede, 1 tuşun sol üst köşesinde bulunan anahtar. –

+0

@Benjamin: Alman klavye düzeninde, sağ tuşun solunda, sağ üst köşede. :) Ayrıca elde etmek için ctrl + alt tuşlarına basmanız gerekiyor ... Her durumda, '' '' kastedilmektedir. – Xeo

+5

Kullandığınız kitaplık bir dizede gerçekten ikili veriyi istiyor mu? İstediğin dosya adı olmadığından emin misin? "Char" tipi hemen hemen tüm platformlarda bir bayt olsa da, ikili verileri depolamak için std :: string işlevini kullanmak bana yanlış geliyor. –

cevap

4

Düşünebildiğim en kolay yöntem. Dosyayı ikili modda açın, ardından tüm şeyi stringstream'a okuyun.

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

Bu tam olarak yaptım. ama ikili verilerin sadece bir kısmını yüklemiş gibi görünüyordu. –

2
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)); 

Böyle kodla std::string görüntü dosyalarını okuyabilir. Dosya boyutlarınızın% 99'undan daha büyük olması için reserve yönteminin parametresini ayarlayın. Sıfır bayt (NULL sonlandırıcı olarak adlandırırsınız), hem ifstream hem de string ile doğru şekilde işlenir.


ben ikili dosya yükleme çeşitli yöntemler karşılaştırıldığında iyi bir article, buldum. En kısa bir

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()); 

Ve burada: Makaleden en hızlı yöntemdir

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

Güncelleme Böyle bir şey geri arama beslemek için kullanılabilir

işlevi (Ben test etmedim):

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(); 
} 
+0

Dün kodumda kısa versiyonu denedim ama bu da işe yaramadı. Buraya daha fazla yardım alabilmem için bugün kodumu almaya çalışacağım. –

2

kütüphane burada kodunuzu yapıştırmak için 'veri' dosya içeriğinde

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); 

olarak geçirilen dize PUT çağrı yapar ve burada 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; 
} 
+0

en azından http://stackoverflow.com/questions/9612121/how-to-read-image-files-and-store-it-in-memorystdstring-in-c/9623954#9623954'e göre dize sıfır bayt depola. hm. –

+0

Evet, dize sıfır bayt depolayabilir. Hata kodunuzun ilk satırında: 'data.c_str()'. Burada sıfır sonlandırılmış dize bir char işaretçi olarak geçirilir. Ve böylece dize ilk sıfır bayt tarafından kesilir. Gereksizleştirilen 'c_str()' yi kaldırın ya da Benjamin'in yönteminden geri aramada 'stringstream' komutunu kullanın ya da' ifstream''i açıp geri aramada kullanabilirsiniz (bu yaklaşım daha iyi performans verir). –

+0

Haklısınız. Geri arama işlevini yeniden yazmam gerektiğini sanırım –

İlgili konular