Frage

Wenn Sie Binärketten (wörtlich String-Objekte, die nur aus 1 und 0), wie würden Sie geben sie als Bits in eine Datei?

Dies ist für einen Text Kompressor Ich arbeite an; es nervt mich immer noch, und es wäre schließlich schön, um es zu arbeiten. Dank!

War es hilfreich?

Lösung

Am einfachsten ist es, einfach acht aufeinanderfolgende Zeichen zu nehmen, schalten Sie sie in ein Byte und Ausgang, Byte. Pad mit Nullen am Ende, wenn Sie das Ende des Datenstroms erkennen können, oder einen Header mit einer Länge hinzufügen (in Bits) am Anfang der Datei.

Die innere Schleife würde in etwa so aussehen:


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

Sie müssen einige Anpassungen vornehmen, aber das ist die allgemeine Idee.

Andere Tipps

Wenn Sie Glück haben, java.math.BigInteger kann alles für Sie tun.

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

Dies ist unabhängig von der Byte-Reihenfolge (Big-Endian) und rechts-Ausrichtung (wenn die Anzahl der Bits, die nicht ein Vielfaches von 8 ist) zu sein, was Sie wollen, aber es kann einfacher sein, um das Array zu ändern später als das zu tun, Zeichenkonvertierung selbst.

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

Und dann ...

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

Angenommen, der String ist ein Vielfaches von acht Bits, (Sie Pad kann es auch anders), nutzen Sie Java gebaut im Integer.valueOf Verfahren beim Parsen, so etwas zu tun:

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

Dann sollten Sie in der Lage sein, das Bytes in einem FileOutputStream ziemlich einfach zu schreiben.

Auf der anderen Seite, wenn Sie für effeciency suchen, sollten Sie nicht einen String unter Verwendung der Bits zu speichern zu beginnen, aber die Bytes direkt in den Kompressor aufbauen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top