2009-06-23 18 views
31

¿Cómo puedo iterar bits en una matriz de bytes?Java Iterate Bits en Byte Array

+0

No se puede.Al menos no directamente. ¿Qué estás tratando de hacer, tal vez hay una mejor manera. Una matriz de bytes contiene una colección de bytes. – OscarRyz

+15

Y una vez más, me gustaría que java.util.BitSet tuviera un constructor de bytes []. –

+0

Se puede hacer. Yo votaría por el método de Jon Skeet. Sin embargo, en la mayoría de los casos cuando se trabaja con bits, hay algunos operadores de bits de lujo que pueden hacer que su tarea sea mucho más rápida. Si nos dice exactamente lo que intenta hacer, podemos ayudarle a encontrar una manera mejor que repetir los bits. – StriplingWarrior

Respuesta

40

Habría que escribir su propia implementación de Iterable<Boolean> que tuvo una matriz de bytes y, a continuación, crea Iterator<Boolean> valores que recuerdan el índice actual en la matriz de bytes y el índice actual dentro del byte actual. A continuación, un método de utilidad como esto sería muy útil:

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

(donde bit rangos de 0 a 7). Cada vez que se llamaba a next(), tenía que incrementar su índice de bits dentro del byte actual e incrementar el índice de bytes dentro de la matriz de bytes si alcanzaba "el noveno bit".

Realmente no es difícil - pero un poco molesto. Avíseme si desea una implementación de ejemplo ...

0

Puede iterar a través de la matriz de bytes, y para cada byte utilice los operadores bit a bit para iterar a través de sus bits.

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

O usando Java modismos

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

@McWaffestix: ¿Esto es C++? – OscarRyz

+3

Diría C# si tuviera que adivinar. –

+0

@mmyers: ¿qué pasa con el "<<" – OscarRyz

0

Necesitaba un poco de bits de streaming en mi solicitud. Here puede encontrar mi implementación de BitArray. No es un patrón de iterador real, pero puede solicitar de 1 a 32 bits de la matriz de forma continua. También hay una implementación alternativa llamada BitReader más adelante en el archivo.

2

Una alternativa sería utilizar un BitInputStream como el que usted puede encontrar here y escribir código como este:

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

(Nota:. Código no contiene EOFException o IOException manipulación por razones de brevedad)

Pero iría con la variante de Jon Skeets y lo haría por mi cuenta.

2

Lo sé, probablemente no sea la forma más "genial" de hacerlo, pero puede extraer cada bit con el siguiente código.

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

Número de bit 1 = 1

Número de bit 2 = 0

número Bit 3 = 0

número

Bit 4 = 1

número Bit 5 = 1

Número de bit 6 = 1

Número de bit 7 = 0

Número de bit 8 = 0

+2

Es genial porque no hace uso de esas operaciones de bits "aterradoras". – Reginaldo

+0

No veo ninguna necesidad de usar el operador bit a bit para algo tan simple como el OP solicitado: iterar a través de los bits. – amischiefr

+3

Esto respondería mejor a la pregunta si mostrara cómo extraer bits de una * matriz de bytes * (en lugar de String o una matriz de caracteres) – 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); 
    } 
}