2009-06-23 6 views
31

Wie kann ich Bits in einem Bytearray iterieren?Java Iterate-Bits in Byte-Array

+0

Sie können nicht.Zumindest nicht direkt. Was versuchst du zu tun, vielleicht gibt es einen besseren Weg. Ein Byte-Array enthält eine Auflistung von Bytes. – OscarRyz

+15

Und noch einmal wünsche ich, dass java.util.BitSet einen byte [] Konstruktor hatte. –

+0

Es kann getan werden. Ich würde mit Jon Skeets Methode stimmen. In den meisten Fällen, wenn Sie mit Bits arbeiten, gibt es einige ausgefallene bitweise Operatoren, die Ihre Aufgabe viel schneller machen können. Wenn Sie uns genau sagen, was Sie gerade tun, können wir Ihnen helfen, einen besseren Weg zu finden, als die Bits zu wiederholen. – StriplingWarrior

Antwort

40

Sie haben würden ein eigene Implementierung von Iterable<Boolean>, die eine Reihe von Bytes nahm zu schreiben, und erstellt dann Iterator<Boolean> Werte, die den aktuellen Index in den Byte-Array und der aktuellen Index innerhalb des aktuellen Byte erinnerten. Dann wird ein Dienstprogramm Methode, wie dies würde sich als nützlich erweisen:

private static Boolean isBitSet(byte b, int bit) 
{ 
    return (b & (1 << bit)) != 0; 
} 

(wo bit im Bereich von 0 bis 7). Jedes Mal, wenn next() aufgerufen wurde, müssten Sie Ihren Bit-Index innerhalb des aktuellen Bytes erhöhen und den Byte-Index innerhalb des Byte-Arrays erhöhen, wenn Sie "das 9. Bit" erreicht haben.

Es ist nicht wirklich hart - aber ein bisschen Schmerz. Lassen Sie mich wissen, wenn Sie eine Beispielimplementierung möchten ...

0

Sie können durch das Bytearray iterieren und für jedes Byte die bitweisen Operatoren verwenden, um seine Bits zu iterieren.

9

Original:

for (int i = 0; i < byteArray.Length; i++) 
{ 
    byte b = byteArray[i]; 
    byte mask = 0x01; 
    for (int j = 0; j < 8; j++) 
    { 
     bool value = b & mask; 
     mask << 1; 
    } 
} 

oder Java mit Idiome

for (byte b : byteArray) { 
    for (int mask = 0x01; mask != 0x100; mask <<= 1) { 
     boolean value = (b & mask) != 0; 
    } 
} 
+0

@McWaffestix: Ist das C++? – OscarRyz

+3

Ich würde C# sagen, wenn ich raten müsste. –

+0

@ mmyers: was ist mit der "<<" – OscarRyz

0

ich einige etwas in meiner Anwendung Streaming benötigt. Here können Sie meine BitArray-Implementierung finden. Es ist kein echtes Iteratormuster, aber Sie können 1-32 Bits vom Array auf Streaming-Art anfordern. Es gibt auch eine alternative Implementierung namens BitReader später in der Datei.

2

Eine Alternative wäre eine BitInputStream wie das verwenden Sie here und schreiben Code wie folgt finden:

BitInputStream bin = new BitInputStream(new ByteArrayInputStream(bytes)); 
    while(true){ 
     int bit = bin.readBit(); 
     // do something 
    } 
bin.close(); 

(Anmerkung:.-Code enthält keine EOFException oder IOException der Kürze der Handhabung)

Aber ich würde mit Jon Skeets Variante gehen und es alleine machen.

2

Ich weiß, wahrscheinlich nicht der "coolste" Weg, es zu tun, aber Sie können jedes Bit mit dem folgenden Code extrahieren.

int n = 156; 

String bin = Integer.toBinaryString(n); 
System.out.println(bin); 

char arr[] = bin.toCharArray(); 
for(int i = 0; i < arr.length; ++i) { 
    System.out.println("Bit number " + (i + 1) + " = " + arr[i]); 
} 

Bitnummer 1 = 1

Bitnummer 2 = 0

Bitnummer 3 = 0

Bitnummer 4 = 1

Bitnummer 5 = 1

Bitnummer 6 = 1

Bitnummer 7 = 0

Bitnummer 8 = 0

+2

Es ist cool, weil es diese "unheimlichen" bitweisen Operationen nicht nutzt. – Reginaldo

+0

Ich sehe keine Notwendigkeit, den bitweisen Operator für etwas zu verwenden, das so einfach ist, wie das OP verlangt: iteriere durch die Bits. – amischiefr

+3

Dies würde die Frage besser beantworten, wenn es zeigt, wie Bits aus einem * Byte-Array * (anstelle von String oder Char-Array) extrahiert werden – Jonik

16
public class ByteArrayBitIterable implements Iterable<Boolean> { 
    private final byte[] array; 

    public ByteArrayBitIterable(byte[] array) { 
     this.array = array; 
    } 

    public Iterator<Boolean> iterator() { 
     return new Iterator<Boolean>() { 
      private int bitIndex = 0; 
      private int arrayIndex = 0; 

      public boolean hasNext() { 
       return (arrayIndex < array.length) && (bitIndex < 8); 
      } 

      public Boolean next() { 
       Boolean val = (array[arrayIndex] >> (7 - bitIndex) & 1) == 1; 
       bitIndex++; 
       if (bitIndex == 8) { 
        bitIndex = 0; 
        arrayIndex++; 
       } 
       return val; 
      } 

      public void remove() { 
       throw new UnsupportedOperationException(); 
      } 
     }; 
    } 

    public static void main(String[] a) { 
     ByteArrayBitIterable test = new ByteArrayBitIterable(
        new byte[]{(byte)0xAA, (byte)0xAA}); 
     for (boolean b : test) 
      System.out.println(b); 
    } 
}