Reputation: 962
I've the following test code. I'd like to know how I can put, and get a String using a Java NIO ByteBuffer. I've added two comments where I need help.
package testPipe;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
public class TestMemBuff {
static final String dataFile = "invoicedata";
static final double[] prices = { 19.99, 9.99, 15.99, 3.99, 4.99 };
static final int[] units = { 12, 8, 13, 29, 50 };
static final String[] descs = { "Java T-shirt", "Java Mug",
"Duke Juggling Dolls", "Java Pin", "Java Key Chain" };
public static Charset charset = Charset.forName("UTF-8");
public static CharsetEncoder encoder = charset.newEncoder();
public static CharsetDecoder decoder = charset.newDecoder();
public static void main(String[] args) throws UnsupportedEncodingException {
double price;
int unit;
String desc;
double total = 0.0;
ByteBuffer buf = ByteBuffer.allocate(1024);
for (int i = 0; i < prices.length; i++) {
buf.putDouble(prices[i]);
buf.putInt(units[i]);
buf.asCharBuffer().put(descs[i]); // Is it correct?
}
buf.flip();
// INPUT
while (buf.hasRemaining()) {
price = buf.getDouble();
unit = buf.getInt();
desc = buf.asCharBuffer().toString(); //This must be wrong!
System.out.format("You ordered %d" + " units of %s at $%.2f%n",
unit, desc, price);
total += unit * price;
}
}
}
This is the output when I execute it:
You ordered 12 units of ????
[...]
and so on.
Thanks for your attention
Upvotes: 2
Views: 13663
Reputation: 1055
Writing part:
for (int i = 0; i < prices.length; i++) {
buf.putDouble(prices[i]);
buf.putInt(units[i]);
byte[] descsBytes = descs[i].getBytes();
buf.putInt(descsBytes.length);
buf.put(descsBytes);
}
Reading part:
while (buf.hasRemaining()) {
price = buf.getDouble();
unit = buf.getInt();
int len = buf.getInt();
byte[] bytes = new byte[len];
buf.get(bytes);
desc = new String(bytes);
System.out.format("You ordered %d" + " units of %s at $%.2f%n",
unit, desc, price);
total += unit * price;
}
Upvotes: 7
Reputation: 1519
ByteBuffer.asCharBuffer()
has a somewhat own behaviour. It creates a new buffer that shares the content with the ByteBuffer but has an own, independent position & limit.
So put() and get() on the CharBuffer do not change the position on the ByteBuffer!
So I would refrain from using ByteBuffer.asCharBuffer()
at all as long as this is not exactly what you need.
So the solution would be to write and read the bytes into the original ByteBuffer:
buf.putInt(descs[i].length);
buf.put(descs[i].getBytes());`
To read the string again read the length and allocate the byte[] yourself:
int stringLength = buf.getInt();
byte[] bytes = new byte[stringLength];
buf.get(bytes);
desc = new String(bytes);
Upvotes: 1