5 votes

Manipulation et sortie de bits en Java

Si vous avez des chaînes binaires (littéralement des objets String qui ne contiennent que des 1 et des 0), comment pouvez-vous les sortir sous forme de bits dans un fichier ?

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

6voto

Tomer Gabel Points 2520

Le plus simple est de prendre simplement 8 caractères consécutifs, de les transformer en un octet et de sortir 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 la 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.

6voto

finnw Points 24592

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) que vous souhaitez, mais il peut être plus simple de modifier le tableau par la suite que de faire la conversion des caractères vous-même.

2voto

izb Points 12736
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 puis...

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

1voto

Dave L. Points 19623

En supposant que la chaîne comporte un multiple de huit bits (vous pouvez la compléter autrement), tirez parti de l'analyse syntaxique intégrée de Java dans la méthode Integer.valueOf pour faire quelque chose comme ceci :

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

Ensuite, vous devriez être en mesure d'écrire les octets dans un fichier de type FileOutputStream assez simplement.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X