Вывод битовых данных в двоичный файл C ++ - PullRequest
6 голосов
/ 01 февраля 2011

Я пишу программу сжатия, и мне нужно записать битовые данные в двоичный файл, используя c ++.Если бы кто-нибудь мог посоветовать письменное заявление или сайт с советами, я был бы очень благодарен.

Извинения, если это простой или запутанный вопрос, я изо всех сил пытаюсь найти ответы в Интернете.

Ответы [ 3 ]

3 голосов
/ 01 февраля 2011

Соберите биты в целые байты, такие как unsigned char или std :: bitset (где размер набора битов кратен CHAR_BIT), затем записывайте целые байты за раз. Компьютеры «работают с битами», но доступная абстракция - особенно для ввода-вывода - это то, что вы, как программист, имеете дело с отдельными байтами. Побитовая манипуляция может использоваться для переключения определенных битов, но вы всегда обрабатываете объекты размером в байт.

В конце вывода, если у вас нет целого байта, вам нужно решить, как его хранить. И iostreams, и stdio могут записывать неформатированные данные, используя ostream :: write и fwrite соответственно.

Вместо одного символа или набора битов <8> (8 является наиболее распространенным значением для CHAR_BIT), вы можете рассмотреть возможность использования блока большего размера, такого как массив из 4-32 или более, символы или эквивалентный размер BitSet.

2 голосов
/ 30 декабря 2011

Для написания двоичного файла наиболее полезный способ, который я нашел, состоит в том, чтобы сохранить весь двоичный файл в виде одного массива в памяти и затем переместить его на жесткий диск. Выполнение бита за раз, или байта за раз, или длинного беззнакового за один раз не так быстро, как хранение всех данных в массиве и использование одного экземпляра "fwrite ()" для сохранения его в жесткий диск.

size_t fwrite (const void * ptr, size_t size, size_t count, FILE * stream);

Ссылка: http://www.cplusplus.com/reference/clibrary/cstdio/fwrite/

На английском:

fwrite ([массив * сохраненных данных], [размер в байтах массива OBJECT. Для беззнаковых символов -> 1, для беззнаковых длинных длинных -> 8], [количество экземпляров в массиве], [FILE *])

Всегда проверяйте свою доходность на предмет подтверждения успеха!

Кроме того, можно привести аргумент о том, что максимально возможный тип объекта - это самый быстрый путь ([unsigned long long]> [char]). Хотя я не разбираюсь в кодировании "fwrite ()", я чувствую, что время для преобразования из естественного объекта, используемого в вашем коде, в [unsigned long long] займет больше времени в сочетании с написанием, чем "fwrite () "делать то, что у тебя есть.

Когда я изучал кодирование Хаффмана, мне потребовалось несколько часов, чтобы понять, что существует разница между [char] и [unsigned char]. Обратите внимание, что для этого метода всегда следует использовать переменные без знака для хранения чистого двоичного файла.

1 голос
/ 31 декабря 2013

по классу ниже вы можете писать и читать по битам

class bitChar{
public:
    unsigned char* c;
    int shift_count;
    string BITS;

    bitChar()
    {
        shift_count = 0;
        c = (unsigned char*)calloc(1, sizeof(char));
    }

    string readByBits(ifstream& inf)
    {
        string s ="";
        char buffer[1];
        while (inf.read (buffer, 1))
        {
            s += getBits(*buffer);
        }
        return s;
    }

    void setBITS(string X)
    {
        BITS = X;
    }

    int insertBits(ofstream& outf)
    {
        int total = 0;

        while(BITS.length())
        {
            if(BITS[0] == '1')
                *c |= 1;
            *c <<= 1;
            ++shift_count;
            ++total;
            BITS.erase(0, 1);

            if(shift_count == 7 )
            {
                if(BITS.size()>0)
                {
                    if(BITS[0] == '1')
                        *c |= 1;
                    ++total;
                    BITS.erase(0, 1);
                }

                writeBits(outf);
                shift_count = 0;
                free(c);
                c = (unsigned char*)calloc(1, sizeof(char));
            }
        }

        if(shift_count > 0)
        {
            *c <<= (7 - shift_count);
            writeBits(outf);
            free(c);
            c = (unsigned char*)calloc(1, sizeof(char));
        }
        outf.close();
        return total;
    }

    string getBits(unsigned char X)
    {
        stringstream itoa;
        for(unsigned s = 7; s > 0 ; s--)
        {
            itoa << ((X >> s) & 1);
        }

        itoa << (X&1) ;
        return itoa.str();
    }

    void writeBits(ofstream& outf)
    {
        outf << *c;
    }

    ~bitChar()
    {
        if(c)
            free(c);
    }
};

для example

#include <iostream>
#include <sstream>
#include <fstream>
#include <string> 
#include <stdlib.h>
using namespace std;


int main()
{
    ofstream outf("Sample.dat");
    ifstream inf("Sample.dat");

    string enCoded = "101000001010101010";

    //write to file
    cout << enCoded << endl ; //print  101000001010101010
    bitChar bchar;
    bchar.setBITS(enCoded);
    bchar.insertBits(outf);

     //read from file
    string decoded =bchar.readByBits(inf);
    cout << decoded << endl ; //print 101000001010101010000000
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...