Pregunta

Si tiene cadenas binarias (literalmente objetos de cadena que contienen solo unos y ceros), ¿cómo las generaría como bits en un archivo?

Esto es para un compresor de texto en el que estaba trabajando;Todavía me molesta y sería bueno que finalmente lo hiciera funcionar.¡Gracias!

¿Fue útil?

Solución

Lo más fácil es simplemente tomar 8 caracteres consecutivos, convertirlos en un byte y generar ese byte.Rellene con ceros al final si puede reconocer el final de la secuencia, o agregue un encabezado con longitud (en bits) al principio del archivo.

El bucle interior se vería así:


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

Necesitará hacer algunos ajustes, pero esa es la idea general.

Otros consejos

Si tiene suerte, java.math.BigInteger puede hacer todo por usted.

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

Esto depende de que el orden de los bytes (big-endian) y la alineación a la derecha (si el número de bits no es múltiplo de 8) sean lo que desee, pero puede ser más sencillo modificar la matriz después que realizar la conversión de caracteres usted mismo. .

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

Y luego...

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

Suponiendo que la cadena tiene un múltiplo de ocho bits (de lo contrario, puede rellenarla), aproveche el análisis integrado de Java en el método Integer.valueOf para hacer algo como esto:

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

Entonces deberías poder escribir los bytes en un FileOutputStream bastante simple.

Por otro lado, si busca eficiencia, debería considerar no usar un String para almacenar los bits para empezar, sino acumular los bytes directamente en su compresor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top