2

The object to which I need to write a ByteBuffer is typed as an instance of interface DataOutput, rather than as an instance of class DataOutputStream (which implements DataOutput). I need to assume ByteBuffer.hasArray() can return false, so I don't have access to any underlying array.

Neither DataOutput nor DataOutputStream provide a write method that accepts a ByteBuffer. However, writing a ByteBuffer to a DataOutputStream can be done with a WritableByteChannel, obtained by passing the OutputStream to a utility method of the Channels class. But DataOutput is not type compatible with OutputStream, and no analogous utility method exists.

Does the SDK provide any efficient routines for doing this? I would rather not have to create an intermediate byte array and loop through the ByteBuffer with bulk get operations (effectively replicating the code of WritableByteChannel implementations).

Nathan Ryan
  • 12,893
  • 4
  • 26
  • 37

1 Answers1

2

I don't believe there is a one-liner for this. A simple while loop should be enough:

DataOutput out = ...
ByteBuffer bb = ...
while (bb.hasRemaining()) {
  out.writeByte(bb.get());
}
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
  • 1
    While that would work and is a reasonable solution for relatively small buffers, it's probably inefficient for the largish buffers I can be expecting. I didn't mention that in my question, though. – Nathan Ryan May 11 '18 at 12:16
  • With this approach there is no intermediate array creation. The only question is what is the implementation of the `DataOutput` and how is it flushed. Perhaps I'm missing something, but what problem could there be for a large `ByteBuffer`? – Karol Dowbecki May 11 '18 at 12:19
  • Your while loop involves two method invocations per byte, whereas an intermediate array involved in a bulk get/write can be used by the implementations of ByteBuffer and DataOutput to perform what are likely to be more efficient array copies of many bytes at a time. Even though I can't access the underlying array of the ByteBuffer, it will probably be backed by one regardless. Same goes for the DataOuput object. – Nathan Ryan May 11 '18 at 12:33