2010-05-24 156 views
3

我有一個Visual Studio 2008 C++應用程序,我想將一個流視爲一組迭代器。從std :: istreambuf_iterator <>複製到std :: vector <>

例如,如果我收到WIN32_FIND_DATA結構在流的陣列,我希望能夠做這樣的事情:

IStreamBuf<WIN32_FIND_DATA> sb(stream); 
std::vector<WIN32_FIND_DATA> buffer; 
std::copy(std::istreambuf_iterator<WIN32_FIND_DATA>(&sb), 
      std::istreambuf_iterator<WIN32_FIND_DATA>(), 
      std::back_inserter(buffer)); 

要做到這一點,我已經定義一個類從std::basic_streambuf<>得出:

template< typename T > 
class IStreamBuf : public std::basic_streambuf<byte> 
{ 
public: 

    IStreamBuf(IStream* stream) : stream_(stream) 
    {   
    }; 

protected: 

    virtual traits_type::int_type underflow() 
    { 
     DWORD bytes_read = 0; 
     HRESULT hr = stream_->Read(&buffer_, sizeof(T), &bytes_read); 
     if(FAILED(hr)) 
      return traits_type::eof(); 

     traits_type::char_type* begin = 
      reinterpret_cast< traits_type::char_type* >(&buffer_); 
     setg(begin, begin, begin + bytes_read); 
     return traits_type::to_int_type(*gptr()); 
    }; 

private: 

    // buffer to hold current item of type T 
    T buffer_; 

    // stream used to receive data 
    IStream* stream_; 
}; // class IStreamBuf 

我無法弄清楚是如何優雅地從byte秒的陣列去的WIN32_FIND_DATA秒的陣列。因爲std::basic_streambuf<>需要std::char_traits<>模板參數,所以我的印象是它只能使用內置類型,如charbyte,而不是像WIN32_FIND_DATA這樣的結構。正確?

關於如何使這項工作的任何建議?

感謝, PaulH

回答

1

istreambuf_iterator作品的緩衝水平,它只是一個字節流。如果要處理結構,則可能需要使用istream_iterator,並創建一個operator>>來讀取WIN32_FIND_DATA結構。您也可以考慮爲WIN32_FIND_DATA創建/使用代理。

+0

我用'std :: istreambuf_iterator's去的原因是'std :: istream_iterator's對格式化輸入進行操作。所以,我會有一些額外的開銷(哨兵對象,流標誌檢查等)。 您可以詳細說明您的意思是「WIN32_FIND_DATA的代理」。最好是一個小例子? – PaulH 2010-05-24 20:00:03

+0

@PaulH:如果您自己從底層緩衝區讀取,則只需處理哨兵對象 - 使用現有流讀取功能從流中讀取數據不需要哨兵對象。示例代理位於:http://stackoverflow.com/questions/2531874/how-might-i-wrap-the-findxfile-style-apis-to-the-stl-style-iterator-pattern-in-c – 2010-05-24 20:17:45

+0

我只是用'istream_iterator'試了一下。它從文件名中過濾掉空白字符。 – PaulH 2010-05-24 21:14:38

相關問題