Question

Si vous avez des chaînes binaires (littéralement, les objets String contenant uniquement des 1 et des 0), comment les exporteriez-vous sous forme de bits dans un fichier?

Ceci est pour un compresseur de texte sur lequel je travaillais; ça me dérange toujours, et ce serait bien de pouvoir enfin le faire fonctionner. Merci!

Était-ce utile?

La solution

Le plus simple consiste simplement à prendre 8 caractères consécutifs, à les transformer en octet et à générer cet octet. Remplissez avec des zéros à la fin si vous pouvez reconnaître la fin du flux ou ajoutez un en-tête avec une longueur (en bits) au début du fichier.

La boucle interne ressemblerait à quelque chose comme:


byte[] buffer = new byte[ ( string.length + 7 ) / 8 ];
for ( int i = 0; i < buffer.length; ++i ) {
   byte current = 0;
   for ( int j = 7; j >= 0; --j )
       if ( string[ i * 8 + j ] == '1' )
           current |= 1 << j;
   output( current );
}

Vous devrez faire quelques ajustements, mais c'est l'idée générale.

Autres conseils

Si vous avez de la chance, java.math.BigInteger peut tout faire pour vous.

String s = "11001010001010101110101001001110";
byte[] bytes = (new java.math.BigInteger(s, 2)).toByteArray();

Cela dépend de l'ordre des octets (big-endian) et de l'alignement à droite (si le nombre de bits n'est pas un multiple de 8), mais il peut être plus simple de modifier le tableau par la suite que de le conversion de personnage vous-même.

public class BitOutputStream extends FilterOutputStream
{
    private int buffer   = 0;
    private int bitCount = 0;

    public BitOutputStream(OutputStream out)
    {
        super(out);
    }

    public void writeBits(int value, int numBits) throws IOException
    {
        while(numBits>0)
        {
            numBits--;
            int mix = ((value&1)<<bitCount++);
            buffer|=mix;
            value>>=1;
            if(bitCount==8)
                align8();
        }
    }

    @Override
    public void close() throws IOException
    {
        align8(); /* Flush any remaining partial bytes */
        super.close();
    }

    public void align8() throws IOException
    {
        if(bitCount > 0)
        {
            bitCount=0;
            write(buffer);
            buffer=0;
        }
    }
}

Et ensuite ...

if (nextChar == '0')
{
    bos.writeBits(0, 1);
}
else
{
    bos.writeBits(1, 1);
}

En supposant que la chaîne comporte un multiple de huit bits (vous pouvez la compléter autrement), profitez de l'analyse intégrée de Java dans la méthode Integer.valueOf pour procéder de la manière suivante:

String s = "11001010001010101110101001001110";
byte[] data = new byte[s.length() / 8];
for (int i = 0; i < data.length; i++) {
    data[i] = (byte) Integer.parseInt(s.substring(i * 8, (i + 1) * 8), 2);
}

Vous devriez alors pouvoir écrire les octets dans un FileOutputStream plutôt simplement.

D'autre part, si vous recherchez une efficacité, vous devriez envisager de ne pas utiliser de chaîne pour stocker les bits pour commencer, mais de créer les octets directement dans votre compresseur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top