2009-09-19 11 views
12

मेरे पास एक मेमोरी ब्लॉक (अपारदर्शी) है, कि मैं अपने सी ++ एडाप्टर के माध्यम से mySQL में ब्लॉब में स्टोर करना चाहता हूं। अनुकूलक एक IStream उम्मीद:मेमोरी बफर में से एक C++ std :: istringstream प्रारंभ करना?

virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0; 

तो मेरे सवाल है: कैसे मैं एक std :: इस स्मृति ब्लॉक से IStream बना सकते हैं (चार * के रूप में टाइप किया)। यह एक स्ट्रिंग नहीं है क्योंकि यह शून्य-समाप्त नहीं हुआ है (लेकिन मुझे इसकी लंबाई की लंबाई पता है)।

मुझे अपनी स्मृति ब्लॉक की प्रतिलिपि किए बिना इसे करने का कोई तरीका नहीं मिला उदाहरण के लिए std :: string में। मुझे लगता है कि यह थोड़ा अपमानजनक है। ऐसा कुछ काम नहीं करता है:

std::streambuf istringbuf(blockPtr, blockLength); 
    std::istringstream tmp_blob(&istringbuf); 

क्योंकि std :: streambuf में ऐसा कोई कन्स्ट्रक्टर नहीं है। मैंने निम्नलिखित सुझाव देखा।

std:: istringstream  tmp_blob; 
    tmp_blob.rdbuf()->pubsetbuf(blockPtr, blockLength); 

क्या यह सही तरीका है? एसटीडी पर

+0

की ([आंतरिक एक मानक धारा (pubsetbuf) द्वारा इस्तेमाल किया बफर स्थापना] संभावित डुप्लिकेट http://stackoverflow.com/questions/1494182/setting-the-internal-buffer- प्रयुक्त-द्वारा-मानक-स्ट्रीम-पबेटबफ) –

उत्तर

7

देखो :: istrstream यह एक निर्माता

istrstream(char* pch, int nLength); 

इस वर्ग के प्रकार का मूल्यह्रास हुआ है है या कम से कम आप सामान्य रूप से अन्य वर्गों का उपयोग करने के कहा जाता है।
स्ट्रस्ट्रीम के साथ समस्या यह है कि char * buffer की स्मृति को प्रबंधित करना अधिक जटिल है, इसलिए सामान्य रूप से आप स्ट्रिंगस्ट्रीम पसंद करेंगे क्योंकि यह आपके लिए स्मृति प्रबंधन करता है। हालांकि इस मामले में आप पहले से ही चार * की स्मृति का प्रबंधन कर रहे हैं, इसलिए इस मामले में सामान्य लाभ एक लागत है। असल में इस मामले में स्ट्रस्ट्रीम ठीक वही करता है जो आप कोड या गति में न्यूनतम ओवरहेड के साथ चाहते हैं। यह ostrsteram by Herb Sutter

+5

हाँ, लेकिन जोसुटिस कहते हैं, "चार * धारा वर्ग केवल पिछड़े संगतता के लिए बनाए रखा जाता है। उनका इंटरफ़ेस त्रुटि प्रवण होता है और उनका शायद ही कभी उपयोग किया जाता है।" यही कारण है कि मैं उनका उपयोग करने के लिए थोड़ा अनिच्छुक था। और "केवल पिछड़े संगतता के लिए बनाए रखा" ऐसा लगता है कि "बेहतर" कक्षाओं का उपयोग करने का एक बेहतर तरीका है। –

+0

मैंने उस लेख को पढ़ा, यह सीधे प्रासंगिक है। धन्यवाद। मुझे लगता है कि मेरे प्रश्न का उत्तर दिया गया है, हालांकि "tmp_blob पर कोई टिप्पणी नहीं है।rdbuf() -> पबेटबफ (ब्लॉकपीआरआर, ब्लॉक लम्बाई); "दृष्टिकोण –

6

Boost.IOStreams की एक स्ट्रीम है जो एक स्ट्रिंगस्ट्रीम की तरह काम करती है, लेकिन मूल सरणी को लपेटती है, इसलिए आप डेटा कॉपी करने से बचते हैं।

std :: stringstream हमेशा अपने स्वयं के आंतरिक बफर

0

untested है, लेकिन शायद लायक एक परीक्षण बनाता है ...

std::stringstream ss; 
ss.write(blockPtr, blockLength); 
ss.seekg(0); 

फिर एस एस के साथ कि setBlob फ़ंक्शन को कॉल करें। आपके पास अभी भी std :: स्ट्रिंगस्ट्रीम में आंतरिक बफर है जैसा कि पहले से ही उल्लेख किया गया है।

37

यह वास्तव में std::streambuf लिखने के लिए बहुत छोटा है जो std::streambuf के सभी वर्चुअल फ़ंक्शंस के डिफ़ॉल्ट व्यवहार के रूप में बफर का उपयोग करता है, 'सही चीज़' करता है। आप केवल setg निर्माण में पढ़ने वाले क्षेत्र और underflow और uflow को traits_type::eof() लौटने के लिए सुरक्षित रूप से छोड़े जा सकते हैं क्योंकि शुरुआती क्षेत्र का अंत धारा का अंत है।

जैसे:

#include <streambuf> 
#include <iostream> 
#include <istream> 
#include <ostream> 

struct OneShotReadBuf : public std::streambuf 
{ 
    OneShotReadBuf(char* s, std::size_t n) 
    { 
     setg(s, s, s + n); 
    } 
}; 

char hw[] = "Hello, World!\n"; 

int main() 
{ 
    // In this case disregard the null terminator 
    OneShotReadBuf osrb(hw, sizeof hw - 1); 
    std::istream istr(&osrb); 

    istr >> std::cout.rdbuf(); 
} 
+0

हाहा, जब मैंने अपना प्रश्न पोस्ट किया तो आपका समाधान खोज परिणामों में नहीं आया। हमें बहुत कुछ मिल गया है;) http: // stackoverflow .com/प्रश्न/2079912/सरल तरह से करने के लिए बनाने-एसी-MemoryStream-से-चार-sizet-बिना-नकल-वें –

संबंधित मुद्दे