3

I have this line of code

String s = new String(m_buffer.array());

where buffer is a ByteBuffer.

Is there a way to convert a bytebuffer to string without allocating a new String and/or involve copying of array of char? (ie, is there a way to just point the String's char[] value to the ByteBuffer's byte[] hb safely?)

Thanks

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Theboy
  • 353
  • 1
  • 2
  • 8
  • 7
    First of all `byte[]` isn't `char[]`, and secondly no. You should be more worried about creating strings from bytes without specifying the encoding. A very good way to end up writing code that breaks as soon as your default encoding changes. – Kayaman Apr 05 '17 at 14:24
  • 4
    Strings are immutable in Java, so that's another reason why this wouldn't be possible. – Steve Smith Apr 05 '17 at 14:25

2 Answers2

7

A way to convert a ByteBuffer to a String would be to use a Charset to decode the bytes:

Charset charset = Charset.forName("ISO-8859-1");

ByteBuffer m_buffer = ...;

String text = charset.decode(m_buffer).toString();

The decoding creates a CharBuffer which you can conveniently convert to a String. You can reuse the CharSet and it is threadsafe. I wouldn't worry too much about performance (re "fastest way") unless you have really a problem in that area. A general advice, when you want to use ByteBuffer, do the to-String conversion as late as possible, and only when the String is needed.

As 14jbella mentioned, Strings are immutable. There is no way of creating a String from an array (char or byte) that does not include copying the data because arrays are mutable. So no, there is no way to do it without copying.

Further you should take into consideration, that m_buffer.array() returns the internal array of the ByteBuffer, which may be much more than the actual data stored in the buffer. Creating a String from that array might lead to a potentially huge memory allocation, because the data gets copied into a new array. For example if you're using a 256 MB ByteBuffer somewhere in your code, and you get a slice() of 32 bytes named m_buffer from that buffer to convert to a String, your invocation of new String(m_buffer.array()) would allocate a new byte array of the size of the original, backing byte array, which is 256 MB, which is probably not that fast, if it requires a GC.

Btw. new String(byte[]) internally uses a CharSet decoder on a ByteBuffer wrapped around your input byte array.

Gerald Mücke
  • 10,724
  • 2
  • 50
  • 67
4

Java's String class is immutable. In order to maintain this guarantee, String has to have its own reference to the char[] backing it, and nobody else may have that reference. If it were to share an array with the ByteBuffer, the String class could not guarantee that it would not be modified. In addition, char, and byte are not the same in Java.

14jbella
  • 505
  • 2
  • 14
  • 1
    Thanks guys. So is my way of doing it the "fastest way" to convert a bytebuffer to string? (like would StringBuilder help?) – Theboy Apr 05 '17 at 14:31