2014-12-15 2 views
4

ByteBuffer предлагает asFloatBuffer() функции. Однако, нет никакого эквивалента FloatBuffer.asByteBuffer()Convert FloatBuffer to ByteBuffer

Я пытаюсь сделать:

float[] array = ... 
try(ByteChannel channel = Files.newByteChannel(path, WRITE, CREATE, TRUNCATE_EXISTING)) { 
    channel.write (FloatBuffer.wrap (array) .asByteBuffer()); 
} 

Есть ли способ эффективно делать это, или мне придется прибегнуть к выделению ByteBuffer как в:

ByteBuffer buffer = ByteBuffer.allocate(array.length * 4); 
buffer .asFloatBuffer() .put (array); 
channel.write (buffer); 
+0

Этот ответ подходит вам? http://stackoverflow.com/questions/7298997/convert-from-floatbuffer-to-byte – ServerSideCat

+0

@ServerSideCat Он уже делает то, что отвечает, что говорит. – markbernard

+1

Вы правы. Другого способа это не делать. – markbernard

ответ

0

Для HeapFloatBuffer, т.е. создано FloatBuffer.allocate или FloatBuffer.wrap, нет простого решения. Пользовательский класс, расширяющий ByteBuffer, должен быть написан.

Для прямых буферов в HotSpot 8, это будет работать в тривиальном случае:

FloatBuffer floatBuffer = ByteBuffer.allocateDirect (...).asFloatBuffer(); 
ByteBuffer byteBuffer = (ByteBuffer) ((sun.nio.ch.DirectBuffer)floatBuffer).attachment(); 

В других ситуациях, использовать следующее. Обратите внимание, что этот класс объявлен в пакете java.nio. Это также, вероятно, будет работать только в HotSpot 8.

package java.nio; 

/** 
* 
* @author Aleksandr Dubinsky 
*/ 
public class BufferUtils { 

     public static ByteBuffer 
    asByteBuffer (FloatBuffer floatBuffer) { 

      if (floatBuffer instanceof DirectFloatBufferU) 
      { 
       DirectFloatBufferU buffer = (DirectFloatBufferU) floatBuffer; 
       return (ByteBuffer) new DirectByteBuffer (buffer.address(), floatBuffer.capacity() * Float.BYTES, buffer) 
              .position (floatBuffer.position() * Float.BYTES) 
              .limit (floatBuffer.limit() * Float.BYTES); 
      } 
      else if (floatBuffer instanceof DirectFloatBufferS) 
      { 
       DirectFloatBufferS buffer = (DirectFloatBufferS) floatBuffer; 
       return (ByteBuffer) new DirectByteBuffer (buffer.address(), floatBuffer.capacity() * Float.BYTES, buffer) 
              .position (floatBuffer.position() * Float.BYTES) 
              .limit (floatBuffer.limit() * Float.BYTES); 
      } 
      else if (floatBuffer instanceof ByteBufferAsFloatBufferB) 
      { 
       ByteBufferAsFloatBufferB buffer = (ByteBufferAsFloatBufferB)floatBuffer; 
       return (ByteBuffer) ((ByteBuffer) buffer.bb 
                 .duplicate() 
                 .position (buffer.offset) 
                 .limit (buffer.offset + buffer.capacity() * Float.BYTES)) 
                 .slice() 
                 .position (buffer.position() * Float.SIZE) 
                 .limit (buffer.limit() * Float.BYTES); 
      } 
      else if (floatBuffer instanceof ByteBufferAsFloatBufferL) 
      { 
       ByteBufferAsFloatBufferL buffer = (ByteBufferAsFloatBufferL)floatBuffer; 
       return (ByteBuffer) ((ByteBuffer) buffer.bb 
                 .duplicate() 
                 .position (buffer.offset) 
                 .limit (buffer.offset + buffer.capacity() * Float.BYTES)) 
                 .slice() 
                 .position (buffer.position() * Float.SIZE) 
                 .limit (buffer.limit() * Float.BYTES); 
      } 
      else 
       throw new IllegalArgumentException ("Unsupported implementing class " + floatBuffer.getClass().getName()); 
     } 

} 
+0

hm, так как FloatBuffer - это только представление, и когда вы можете сначала создать BB, вы можете использовать 'ByteBuffer bb = ByteBuffer, allocate(); FloatBuffer fb = bb.asFloatBuffer(); ', они имеют одну и ту же поддержку. – eckes

+0

@eckes Вопрос предполагает, что вы потеряли ссылку на оригинальный ByteBuffer. –

+0

Ну его вопрос, но код не показывает никаких бродячих FloatBuffers ... – eckes