I need String of size
got
You can use String constructor String(char[] value,int offset,int count)
String s = new String(buf,0,got);
Sample code:
char buf[] = new char[4096];
buf[0]='a';
buf[1]='b';
buf[2]='c';
int got = 2;
String s = new String(buf,0,got);
System.out.println(s); // ab
Answer from Braj on Stack OverflowI need String of size
got
You can use String constructor String(char[] value,int offset,int count)
String s = new String(buf,0,got);
Sample code:
char buf[] = new char[4096];
buf[0]='a';
buf[1]='b';
buf[2]='c';
int got = 2;
String s = new String(buf,0,got);
System.out.println(s); // ab
You can use a StringBuffer. This is like a String, but mutable. So, for example, something like:
StringBuffer sbuff = new StringBuffer();
sbuff.append(buf);
sbuff.setLength(got);
String buffString = sbuff.toString();
Java ByteBuffer to String - Stack Overflow
arrays - Convert ByteBuffer to String in Java - Stack Overflow
ByteBuffer to String
java - What is the difference in converting string buffer to string using .toString(), String.valueOf() and + " " - Stack Overflow
There is simpler approach to decode a ByteBuffer into a String without any problems, mentioned by Andy Thomas.
String s = StandardCharsets.UTF_8.decode(byteBuffer).toString();
EDIT (2018): The edited sibling answer by @xinyongCheng is a simpler approach, and should be the accepted answer.
Your approach would be reasonable if you knew the bytes are in the platform's default charset. In your example, this is true because k.getBytes() returns the bytes in the platform's default charset.
More frequently, you'll want to specify the encoding. However, there's a simpler way to do that than the question you linked. The String API provides methods that converts between a String and a byte[] array in a particular encoding. These methods suggest using CharsetEncoder/CharsetDecoder "when more control over the decoding [encoding] process is required."
To get the bytes from a String in a particular encoding, you can use a sibling getBytes() method:
byte[] bytes = k.getBytes( StandardCharsets.UTF_8 );
To put bytes with a particular encoding into a String, you can use a different String constructor:
String v = new String( bytes, StandardCharsets.UTF_8 );
Note that ByteBuffer.array() is an optional operation. If you've constructed your ByteBuffer with an array, you can use that array directly. Otherwise, if you want to be safe, use ByteBuffer.get(byte[] dst, int offset, int length) to get bytes from the buffer into a byte array.
You need to use the buffer's position and limit to determine the number of bytes to read.
// ...populate the buffer...
buffer.flip(); // flip the buffer for reading
byte[] bytes = new byte[buffer.remaining()]; // create a byte array the length of the number of bytes written to the buffer
buffer.get(bytes); // read the bytes that were written
String packet = new String(bytes);
In my opinion you shouldn't really be using the backing array() at all; it's bad practice. Direct byte buffers (created by ByteBuffer.allocateDirect() won't have a backing array and will throw an exception when you try to call ByteBuffer.array(). Because of this, for portability you should try to stick to the standard buffer get and put methods. Of course, if you really want to use the array you can use ByteBuffer.hasArray() to check if the buffer has a backing array.
The answer talking about setting range from position to limit is not correct in a general case. When the buffer has been partially consumed, or is referring to a part of an array (you can ByteBuffer.wrap an array at a given offset, not necessarily from the beginning), we have to account for that in our calculations. This is the general solution that works for buffers in all cases (does not cover encoding):
if (myByteBuffer.hasArray()) {
return new String(myByteBuffer.array(),
myByteBuffer.arrayOffset() + myByteBuffer.position(),
myByteBuffer.remaining());
} else {
final byte[] b = new byte[myByteBuffer.remaining()];
myByteBuffer.duplicate().get(b);
return new String(b);
}
For the concerns related to encoding, see Andy Thomas' answer.
Hi Guys,
Could anyone please tell me how I can convert a ByteBuffer to a String? I thought it would be a simple function but I can't seem to work it out.
This is just a part of what I have written. I am essentially trying to read a message sent via TCP. There were intermediate steps which I didn't think were necessary to include here.
ServerSocketChannel tcpserver = ServerSocketChannel.open(); SocketChannel connectionSocket = tcpserver.accept(); // create buffer to hold message ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = connectionSocket.read(buf);
While googling around, there was talk of paying attention to character encoding. Could someone please explain how this factors into the problem at hand?
Any help would be greatly appreciated!!
Kind Regards,
Giri
This
StringBuffer sb = new StringBuffer("Welcome");
String st = sb + "";
will result more or less in
StringBuffer sb = new StringBuffer("Welcome");
StringBuilder builder = new StringBuilder();
builder.append((sb == null) ? "null" : sb.toString());
builder.append("");
String st = builder.toString();
If we compile them into two methods in java
private StringBuffer sb = new StringBuffer("Welcome");
public String testToString() {
return sb.toString();
}
public String testAppend() {
return sb + "";
}
and then use javap -v, we get
public java.lang.String testToString();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: getfield #19 // Field sb:Ljava/lang/StringBuffer;
4: invokevirtual #27 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
7: areturn
LineNumberTable:
line 10: 0
LocalVariableTable:
Start Length Slot Name Signature
0 8 0 this Lcom/stackoverflow/Question;
public java.lang.String testAppend();
descriptor: ()Ljava/lang/String;
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: new #31 // class java/lang/StringBuilder
3: dup
4: invokespecial #33 // Method java/lang/StringBuilder."<init>":()V
7: aload_0
8: getfield #19 // Field sb:Ljava/lang/StringBuffer;
11: invokevirtual #34 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
14: invokevirtual #38 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
17: areturn
LineNumberTable:
line 14: 0
LocalVariableTable:
Start Length Slot Name Signature
0 18 0 this Lcom/stackoverflow/Question;
So appending appears to be slightly less efficient as it uses an extra bit of stack and contains more instructions.