我是新來提升和它的iostreams包,並找到了一點文件。希望有人會讓我直率。我試圖轉換一小段C#流代碼,我寫了一段時間回讀壓縮流。從一個文件的一部分boost :: iostreams管理資源
byte[] data = new byte[length - 1];
file.Read(data, 0, data.Length);
Stream ret = new ZlibStream(new MemoryStream(data), CompressionMode.Decompress, true);
return ret;
的數據被讀入饋送ZLIB解壓縮器存儲器緩衝器。隨着時間的推移,流的消費者將接受它,並且當它結束時將呼叫Close()
,其與垃圾收集器結合將清理所有資源。 注意:一個重要的區別是我不想解壓縮整個文件,只是一個小部分。該文件已被查找到一些內部位置,長度相對於文件的全部大小而言較小。
我想在C++代碼中用Boost提出最好的等價物。到目前爲止,我有這種道德等同於上述(未經測試):
char * data = new char[length - 1];
_file.read(data, length - 1);
io::stream_buffer<io::basic_array_source<char> > buffer(data, length - 1);
io::filtering_stream<io::input> * in = new io::filtering_stream<io::input>;
in->push(io::zlib_decompressor());
in->push(buffer);
return in;
我以爲我能回到裹在shared_ptr
這將節省消費者不必擔心刪除流filtering_stream,但我也有那裏的數據緩衝區已經新增了。理想情況下,我希望消費者只需在流上調用close()
,並且某些機制(例如回調)將清理過濾器中的基礎資源。要求消費者將流傳遞給顯式釋放函數也是可以接受的,但我仍然不完全確定如何首先獲取底層數據緩衝區。
清潔的替代解決方案也受到歡迎。
更新1
我試圖抓住鬆散由貓加加上約一個std :: vector的支持驅動程序的評論。這不是我所做的,但這是我迄今爲止提出的。在下面的代碼中,我有一個boost :: shared_array支持的驅動程序,基於boost驅動程序示例。
namespace io = boost::iostreams;
class shared_array_source
{
public:
typedef char char_type;
typedef io::source_tag category;
shared_array_source (boost::shared_array<char> s, std::streamsize n)
: _data(s), _pos(0), _len(n)
{ }
std::streamsize read (char * s, std::streamsize n)
{
std::streamsize amt = _len - _pos;
std::streamsize result = (std::min)(amt, n);
if (result != 0) {
std::copy(_data.get() + _pos, _data.get() + _pos + result, s);
return result;
}
else {
return -1;
}
}
private:
boost::shared_array<char> _data;
std::streamsize _pos;
std::streamsize _len;
};
然後,我有我的函數返回一個流
io::filtering_istream * GetInputStream (...)
{
// ... manipulations on _file, etc.
boost::shared_array<char> data(new char[length - 1]);
_file.read(data.get(), length - 1);
shared_array_source src(data, length - 1);
io::stream<shared_array_source> buffer(src);
io::filtering_istream * in = new io::filtering_istream;
in->push(io::zlib_decompressor());
in->push(buffer);
// Exhibit A
// uint32_t ui;
// rstr->read((char *)&ui, 4);
return in;
}
在我的測試程序的主要功能:
int main() {
boost::iostreams::filtering_istream * istr = GetInputStream();
// Exhibit B
uint32_t ui;
rstr->read((char *)&ui, 4);
return 0;
}
忽略我正在返回一個指針的事實那永遠不會被釋放 - 我儘可能保持簡單。當我運行這個時會發生什麼?如果我在圖表A取消註釋代碼,我會在ui
中獲得正確的讀數。但是當我打開圖表B時,我深深地深陷在Boost(有時)中。那麼廢話,我超出了範圍,事情打破了,一些地方必須解構和搞亂一切。 data
在shared_array中,in
在堆上,壓縮機根據文檔構建。
其中一個boost構造函數或函數獲取對堆棧中對象的引用(即io :: stream或filtering_stream的推送)?如果是這樣的話,我可以回到原來的方式,在堆上放置unmananaged對象。
_pos總是等於0否? 你永遠不會爲它分配任何值。 – 2017-05-10 10:07:10