2011-02-01 14 views
6

Sto scrivendo un programma di compressione e ho bisogno di scrivere dati bit in un file binario usando C++. Se qualcuno potesse consigliarvi sulla dichiarazione scritta, o su un sito web con consigli, sarei molto grato.Invio di dati bit al file binario C++

Mi scuso se questa è una domanda semplice o confusa, sto cercando di trovare risposte sul web.

risposta

3

Raccogliere i bit in byte interi, come un char senza segno o std :: bitset (dove la dimensione del set di bit è un multiplo di CHAR_BIT), quindi scrivere interi byte alla volta. I computer "trattano i bit", ma l'astrazione disponibile - specialmente per l'IO - è che tu, come programmatore, gestisci i singoli byte. È possibile utilizzare la manipolazione bit per bit per alternare bit specifici, ma si gestiscono sempre oggetti di dimensioni pari a byte.

Alla fine dell'output, se non si dispone di un intero byte, è necessario decidere come deve essere memorizzato. Sia iostreams che stdio possono scrivere dati non formattati usando rispettivamente ostream :: write e fwrite.

Invece di un singolo carattere o set di bit < 8> (8 è il valore più comune per CHAR_BIT), è possibile considerare l'utilizzo di una dimensione di blocco più grande, ad esempio un array di 4-32 o più caratteri o l'equivalente bitset di dimensioni ridotte.

+0

Grazie Fred per i vostri consigli, che mi ha dato una maniglia su dove andare a cercare. –

2

Per la scrittura di binari, il trucco che ho trovato più utile è archiviare tutto il binario come un singolo array in memoria e quindi spostarlo tutto sul disco rigido. Fare un po 'alla volta, o un byte alla volta, o un unsigned long long alla volta non è veloce come avere tutti i dati memorizzati in una matrice e usare un'istanza di "fwrite()" per memorizzarla sul disco rigido.

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

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

In inglese:.

fwrite ([gamma * di dati memorizzati], [dimensione in byte di matrice di oggetti per i caratteri non firmati -> 1, per lunghi long senza segno -> 8 ], [numero di istanze nell'array], [FILE *])

Controllare sempre i resi per la convalida del successo!

Inoltre, un argomento può essere fatto che avere il tipo di oggetto più grande possibile è il modo più veloce per andare ([unsigned long long]> [char]). Mentre non sono esperto nella codifica di "fwrite()", sento che il tempo di convertire dall'oggetto naturale usato nel tuo codice a [unsigned long long] richiederà più tempo se combinato con la scrittura rispetto a "fwrite() "fare il dovuto con quello che hai.

Indietro quando stavo imparando Huffman Coding, mi ci sono volute alcune ore per capire che c'era una differenza tra [char] e [unsigned char]. Nota per questo metodo che devi sempre usare le variabili non firmate per memorizzare il puro binario.

1

per classe di seguito è possibile scrivere e leggere po 'a poco

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); 
    } 
}; 

per 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; 
}