Domanda

Se disponi di stringhe binarie (letteralmente oggetti String che contengono solo 1 e 0), come potresti stamparle come bit in un file?

Questo è per un compressore di testo su cui stavo lavorando;mi dà ancora fastidio e sarebbe bello farlo finalmente funzionare.Grazie!

È stato utile?

Soluzione

Il modo più semplice è semplicemente prendere 8 caratteri consecutivi, trasformarli in un byte e visualizzare quel byte.Completa con zeri alla fine se riesci a riconoscere la fine del flusso o aggiungi un'intestazione con la lunghezza (in bit) all'inizio del file.

Il ciclo interno sarebbe simile a:


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

Dovrai apportare alcune modifiche, ma questa è l'idea generale.

Altri suggerimenti

Se sei fortunato, java.math.BigInteger può fare tutto per te.

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

Ciò dipende dal fatto che l'ordine dei byte (big-endian) e l'allineamento a destra (se il numero di bit non è un multiplo di 8) siano ciò che desideri, ma potrebbe essere più semplice modificare l'array in seguito piuttosto che eseguire tu stesso la conversione dei caratteri .

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

Poi...

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

Supponendo che la stringa abbia un multiplo di otto bit (puoi riempirla altrimenti), sfrutta l'analisi integrata di Java nel metodo Integer.valueOf per fare qualcosa del genere:

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

Quindi dovresti essere in grado di scrivere i byte in a FileOutputStream abbastanza semplicemente.

D'altra parte, se cerchi l'efficienza, dovresti considerare di non utilizzare una stringa per memorizzare i bit all'inizio, ma di creare i byte direttamente nel tuo compressore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top