将FloatBuffer转换为ByteBuffer

ByteBuffer提供asFloatBuffer()函数。 但是,没有等效的FloatBuffer.asByteBuffer()

我想做:

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

对于HeapFloatBuffer ,即由FloatBuffer.allocateFloatBuffer.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()); } }