[英]write std::bitset to binary file and load the file to std:bitset
[英]Binary Serialization of std::bitset
std::bitset
具有to_string()
用於序列作為方法char
的基於字符串1
秒和0
秒。 顯然,這對bitset中的每個位使用一個8位char
,使序列化表示比所需的時間長8倍。
我想將bitset存儲在二進制表示中以節省空間。 只有當我的bitset中少於32位時, to_ulong()
方法才有意義。 我有幾百個。
我不確定我是否想在對象(地址)本身上使用memcpy()
/ std::copy()
,因為它假定對象是POD。
API似乎沒有提供內部數組表示的句柄,我可以從中獲取地址。
我還想選擇從二進制表示中反序列化bitset。
我怎樣才能做到這一點?
這是一種基於顯式創建std::vector<unsigned char>
,一次讀取/寫入一位...
template<size_t N>
std::vector<unsigned char> bitset_to_bytes(const std::bitset<N>& bs)
{
std::vector<unsigned char> result((N + 7) >> 3);
for (int j=0; j<int(N); j++)
result[j>>3] |= (bs[j] << (j & 7));
return result;
}
template<size_t N>
std::bitset<N> bitset_from_bytes(const std::vector<unsigned char>& buf)
{
assert(buf.size() == ((N + 7) >> 3));
std::bitset<N> result;
for (int j=0; j<int(N); j++)
result[j] = ((buf[j>>3] >> (j & 7)) & 1);
return result;
}
注意,要調用反序列化模板函數bitset_from_bytes
,必須在函數調用bitset_from_bytes
大小N
,例如
std::bitset<N> bs1;
...
std::vector<unsigned char> buffer = bitset_to_bytes(bs1);
...
std::bitset<N> bs2 = bitset_from_bytes<N>(buffer);
如果你真的關心速度一個解決方案將獲得一些東西將進行循環展開,以便打包例如一次完成一個字節,但更好的只是編寫自己的bitset實現,不隱藏內部二進制表示而不是使用std::bitset
。
正如gamedev.net上的人所建議的,可以嘗試使用boost :: dynamic_bitset,因為它允許訪問bitpacked數據的內部表示。
編輯:以下內容無法正常工作。 顯然,“二進制格式”實際上意味着“二進制的ASCII表示”。
您應該能夠使用operator<<
將它們寫入std::ostream
。 它在這里說:
[Bitsets]也可以直接插入並以二進制格式從流中提取。
回答我自己的問題是否完整。
顯然,有這樣的沒有簡單和可移植的方法。
為了簡單起見(雖然不是效率),我最終使用to_string
,然后從字符串的所有32位塊(以及余數*)創建連續的32位位集,並在每個上使用to_ulong
將這些位收集到二進制緩沖區。
這種方法讓STL本身有點笨拙,盡管它可能不是最有效的方法。
* 請注意,由於std::bitset
是在總位數上進行模板化的,因此余數位集需要使用一些簡單的模板元編程算法。
除了轉換為字符串並執行自己的字符串序列化之外,我看不到一種明顯的方法,該字符串將8個字符的塊組合成一個序列化字節。
編輯:更好的是用operator[]
迭代所有位並手動序列化它。
這可能對您有所幫助,它是各種序列化類型的一個小例子。 我添加了bitset和raw位值,可以像下面這樣使用。
( https://github.com/goblinhack/simple-c-plus-plus-serializer上的所有示例)
class BitsetClass {
public:
std::bitset<1> a;
std::bitset<2> b;
std::bitset<3> c;
unsigned int d:1; // need c++20 for default initializers for bitfields
unsigned int e:2;
unsigned int f:3;
BitsetClass(void) { d = 0; e = 0; f = 0; }
friend std::ostream& operator<<(std::ostream &out,
Bits<const class BitsetClass & > const m
{
out << bits(my.t.a);
out << bits(my.t.b);
out << bits(my.t.c);
std::bitset<6> s(my.t.d | my.t.e << 1 | my.t.f << 3);
out << bits(s);
return (out);
}
friend std::istream& operator>>(std::istream &in,
Bits<class BitsetClass &> my)
{
std::bitset<1> a;
in >> bits(a);
my.t.a = a;
in >> bits(my.t.b);
in >> bits(my.t.c);
std::bitset<6> s;
in >> bits(s);
unsigned long raw_bits = static_cast<unsigned long>(s.to_ulong());
my.t.d = raw_bits & 0b000001;
my.t.e = (raw_bits & 0b000110) >> 1;
my.t.f = (raw_bits & 0b111000) >> 3;
return (in);
}
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.