How to store a <bool> vector or bit set in a file, but bit-wise?

How to write bit data to a file?

The first answer does not answer the question correctly, since it takes 8 times more space than necessary.

How would you do that? I really need this to save a lot of true / false values.

+5
source share
6 answers

The easiest approach: take consecutive 8 logical values, represent them as one byte, write this byte to your file. This will save a lot of space.

, ; !

+5

, , , unsigned long, :: dynamic_bitset. ( , , 32 64 , ).

dynamic_bitset to_block_range . dynamic_bitset , from_block_range BlockInputIterator append().

(), .

"": , , , , . endianness (, ntohl, , , -endian, , , ).

(: , boost:: dynamic_bitset , . ).

, os.write( &data[0], sizeof(Block) * nBlocks ), . read( &data[0], sizeof(Block) * nBlocks ), vector<Block>, data.resize(nBlocks) (not reserve()). ( istream_iterator istreambuf_iterator, (), , ).

+2

:

std::vector<bool> data = /* obtain bits somehow */

// Reserve an appropriate number of byte-sized buckets.
std::vector<char> bytes((int)std::ceil((float)data.size() / CHAR_BITS)); 

for(int byteIndex = 0; byteIndex < bytes.size(); ++byteIndex) {
   for(int bitIndex = 0; bitIndex < CHAR_BITS; ++bitIndex) {
       int bit = data[byteIndex * CHAR_BITS + bitIndex];

       bytes[byteIndex] |= bit << bitIndex;
   }
}

, , , - , . , , ( , , CHAR_BITS), , .

( , 1am, - ).

+1

, , .

template<int I>
void bitset_dump(const std::bitset<I> &in, std::ostream &out)
{
    // export a bitset consisting of I bits to an output stream.
    // Eight bits are stored to a single stream byte.
    unsigned int i = 0;  // the current bit index
    unsigned char c = 0; // the current byte
    short bits = 0;      // to process next byte
    while(i < in.size())
    {
        c = c << 1;       //
        if(in.at(i)) ++c; // adding 1 if bit is true
        ++bits;
        if(bits == 8)
        {
            out.put((char)c);
            c = 0;
            bits = 0;
        }
        ++i;
    }
    // dump remaining
    if(bits != 0) {
        // pad the byte so that first bits are in the most significant positions.
        while(bits != 8)
        {
            c = c << 1;
            ++bits;
        }
        out.put((char)c);
    }
    return;
}

template<int I>
void bitset_restore(std::istream &in, std::bitset<I> &out)
{
    // read bytes from the input stream to a bitset of size I.
    /* for debug */ //for(int n = 0; n < I; ++n) out.at(n) = false;
    unsigned int i = 0;          // current bit index
    unsigned char mask = 0x80;   // current byte mask
    unsigned char c = 0;         // current byte in stream
    while(in.good() && (i < I))
    {
        if((i%8) == 0)           // retrieve next character
        { c = in.get();
          mask = 0x80;
        }
        else mask = mask >> 1;   // shift mask
        out.at(i) = (c & mask);
        ++i;
    }
}

, , , reinterpret_cast , , , , , , (endianness?)

+1
#include "stdio"
#include "bitset"
...
FILE* pFile;
pFile = fopen("output.dat", "wb");
...
const unsigned int size = 1024;
bitset<size> bitbuffer;
...
fwrite (&bitbuffer, 1, size/8, pFile);
fclose(pFile);
0

:

( , ) .

8 , .

-1

All Articles