2014-04-22 25 views
5

Jak mogę połączyć dwa ByteBuffery z jednym ByteBufferem?Concat two ByteBuffers in Java

Następujące nie działa:

ByteBuffer bb = ByteBuffer.allocate(100); 
    ByteBuffer bb2 = ByteBuffer.allocate(200); 
    bb.allocate(200).put(bb2); 
    System.out.println(bb.array().length); 

Długość bb wciąż 100.

Odpowiedz

8

Coś podobnego

bb = ByteBuffer.allocate(300).put(bb).put(bb2); 

powinien wykonać zadanie: Tworzenie bufora, który jest wystarczająco duży, aby pomieścić zawartość obydwu buforów, a następnie użyć względny put-metody, aby wypełnić go pierwszym i drugim buforem. (Metoda ta zwraca przy okazji instancję, do której metoda została wywołana)

+3

** OSTRZEŻENIE: ** 'position' i' limit' będą ustawione na 'pojemność', która prawdopodobnie ** nie ** jest tym, czego oczekiwałbyś lub chciałbyś, jeśli zamierzasz przetworzyć wynikowy' ByteBuffer'. Będziesz chciał wywołać '.flip()', aby móc przetworzyć całą zawartość zwróconego 'ByteBuffer', dodając na końcu' .flip(); '. –

+0

Tak, 'flip()' lub 'position (0)' (Ja osobiście uważam, że ten ostatni jest bardziej czytelny) – Marco13

-1

Wypróbuj poniższy kod:

//store both ByteBuffer object as an array 
byte[] array1 = ByteBuffer.allocate(100).array(); 
byte[] array2 = ByteBuffer.allocate(200).array(); 

//create a ByteBuffer which is big enough 
ByteBuffer bigenough = ByteBuffer.allocate(array1.length + array2.length); 

//put the two arrays in one ByteBuffer 
ByteBuffer after1 = bigenough.put(array1, 0, array1.length); 
ByteBuffer result = after1.put(array2, array1.length, array2.length); 

//print the length of the combined array. 
System.out.println(result.array().length); 
+0

wynik ma długość 200. Spodziewałem się, że będę 300. –

+0

Poprawiłem na anser. Ale czy przyjrzałeś się samemu połączeniu samych tablic? Czy ByteBuffer jest niezbędny do użycia? –

-2

Oto miły sposób, który dołącza do dowolnej liczby instancji ByteBuffer. Te metody zostały wyodrębnione z utworzonej klasy Joiner, która ma o wiele więcej niż zwykłe dołączenie do instancji ByteBuffer.

Wyodrębniłem tylko metody odnoszące się do tego pytania i nie opublikowałem reszty klasy ze względu na zwięzłość.

Zapewnia to szerokie zastosowanie Guawy dla wygody. Jeśli nie chcesz używać Guava, zastąpienie kodu Guava jest ćwiczeniem dla czytelnika.

public ByteBuffer join(@Nonnull final Iterable<ByteBuffer> iterable) 
{ 
    /* in the actual code this is separate class, it is included here 
     like this for brevity */ 
    @SuppressWarnings("ConstantConditions") 
    final Function<Iterable<Integer>,Integer> sum = new Function<Iterable<Integer>,Integer>(){ 
     private int sum = 0; 
     @Nullable 
     @Override 
     public Integer apply(@Nullable final Iterable<Integer> input) 
     { 
      for (final Integer i : checkNotNull(input)) { sum += i; } 
      return sum; 
     } 
    }; 
    final int byteCount = sum.apply(Iterables.transform(iterable, new Function<ByteBuffer, Integer>() 
    { 
     @Nullable 
     @Override 
     public Integer apply(@Nullable final ByteBuffer input) 
     { 
      return checkNotNull(input).remaining(); 
     } 
    })); 
    final ByteBuffer bb = ByteBuffer.allocate(byteCount); 
    for (final ByteBuffer b : iterable) 
    { 
     bb.put(b); 
    } 
    bb.flip(); /* this is very important */ 
    return bb; 
} 

@Override 
public ByteBuffer join(@Nonnull final List<ByteBuffer> list) 
{ 
    return this.join((Iterable<ByteBuffer>) list); 
} 

@Override 
public ByteBuffer join(@Nonnull final Set<ByteBuffer> set) 
{ 
    return this.join((Iterable<ByteBuffer>) set); 
} 

@Override 
public ByteBuffer join(@Nonnull final ByteBuffer... varargs) 
{ 
    return this.join((Iterable<ByteBuffer>) Arrays.asList(varargs)); 
} 
0

Będziemy kopiować wszystkie dane. Pamiętaj, że właśnie dlatego połączenie strun jest drogie!

public static ByteBuffer concat(final ByteBuffer... buffers) { 
    final ByteBuffer combined = ByteBuffer.allocate(Arrays.stream(buffers).mapToInt(Buffer::remaining).sum()); 
    Arrays.stream(buffers).forEach(b -> combined.put(b.duplicate())); 
    return combined; 
}