Question

Je suis en train d'écrire un programme de compression, et le besoin d'écrire des données de bits dans un fichier binaire en utilisant c ++. Si quelqu'un pouvait donner des conseils sur la déclaration d'écriture, ou un site Web avec des conseils, je serais très reconnaissant.

Toutes mes excuses si cela est simple ou question confuse, je me bats pour trouver des réponses sur le web.

Était-ce utile?

La solution

Recueillir les bits en octets entiers, tels que un unsigned char ou std :: bitset (où la taille de bitset est un multiple de CHAR_BIT), puis d'écrire les octets entiers à la fois. Ordinateurs « traitent avec des morceaux », mais l'abstraction disponible - en particulier pour IO - est que vous, en tant que programmeur, beaucoup avec des octets individuels. la manipulation Bitwise peut être utilisé pour bits spécifiques bascule, mais vous manipulez toujours des objets de taille octet.

A la fin de la sortie, si vous ne disposez pas d'un octet entier, vous aurez besoin de décider comment cela doit être conservé. Les deux iostreams et stdio peuvent écrire des données non formatées en utilisant ostream :: écriture et fwrite, respectivement.

Au lieu d'un seul char ou bitset <8> (8 étant la plus commune pour la valeur CHAR_BIT), vous pouvez envisager d'utiliser une taille de bloc plus grand, comme un tableau de 4-32, ou plus, ou l'équivalent caractères de taille bitset.

Autres conseils

Pour l'écriture binaire, le truc que j'ai trouvé le plus utile est de stocker tous les binaires comme un seul tableau en mémoire, puis déplacez-le sur tout le disque dur. Faire un peu à un moment ou un octet à un moment ou un unsigned long long à la fois est pas aussi rapide que d'avoir toutes les données stockées dans un tableau et en utilisant une instance de « fwrite () » pour stocker au disque dur.

size_t fwrite (const void * ptr, taille size_t, compte size_t, FILE * flux);

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

En anglais:

fwrite ([tableau * des données stockées], [FICHIER *], [nombre d'instances en tableau] [taille en octets objet tableau pour les caractères non signés -.> 8 -> 1, pour languit unsigned long])

Vérifiez toujours vos déclarations pour la validation de la réussite!

En outre, un argument peut être fait que d'avoir le type d'objet soit aussi grand que possible est le moyen le plus rapide d'aller ([unsigned long long]> [char]). Bien que je ne suis pas versé dans le codage derrière « fwrite () », je me sens le temps de convertir de l'objet naturel utilisé dans votre code [unsigned long long] prendra plus de temps lorsqu'il est combiné avec l'écriture que la « fwrite () «faire en raison de ce que vous avez.

Quand j'apprenais le codage de Huffman, il m'a fallu quelques heures pour se rendre compte qu'il y avait une différence entre [char] et [unsigned char]. Avis pour cette méthode que vous devriez toujours utiliser des variables non signées pour stocker le binaire pur.

par classe ci-dessous, vous pouvez lire et écrire bit par bit

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

pour 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;
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top