2011-02-01 6 views
6

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

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

ответ

3

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

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

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

+0

Спасибо Фреда за совет, который дал мне ручку, где искать. –

2

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

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

Ref: http://www.cplusplus.com/reference/clibrary/cstdio/fwrite/

На английском языке:.

FWRITE ([массив * хранимых данных], [размер в байтах массива ОБЪЕКТА Для беззнаковых символов -> 1, для беззнаковых длинных лонги -> 8 ], [количество экземпляров в массиве], [ФАЙЛ *])

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

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

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

1

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

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; 
} 
Смежные вопросы