Java NIO: чтение блоков переменного размера - PullRequest
3 голосов
/ 23 августа 2009

Я хотел бы прочитать строку из потока TCP, которая дана с длиной байта, сопровождаемой фактическими данными. В Python я бы сделал

length = ord(stream.read(1))
data = stream.read(length)

Как мне сделать то же самое в Java NIO? У меня есть буфер (емкостью 257)

stream.read(buffer); // cannot specify a size here
int length = buffer.get();
byte[] data = new byte[length];
buffer.get(data);

К сожалению, это не работает: get () вызывает чтение мимо данных в буфере: - (

Возможно, мне нужна какая-то комбинация переворота, перемотки, сброса и т. Д., Но я не могу понять это.

Ответы [ 2 ]

5 голосов
/ 23 августа 2009

если stream является SocketChannel и buffer является ByteBuffer, вы можете сделать следующее:

//assuming buffer is a ByteBuffer
buffer.position(0);
buffer.limit(1);
while (buffer.hasRemaining()) { 
   stream.read(buffer);
}
buffer.rewind();

//get the byte and cast it into the range 0-255
int length = buffer.get() & 0xFF;
buffer.clear();
buffer.limit(length);
while (buffer.hasRemaining()) { 
   stream.read(buffer);
}
buffer.rewind();
//the buffer is now ready for reading the data from
0 голосов
/ 23 августа 2009

Предлагаю вам взглянуть на java.nio.channel.GatheringByteChannel и DatagramChannel. Вам нужно будет указать датаграмму для своих нужд.

Это то, что вы сделали на своем примере с Python (первый байт указывает на длину полезной нагрузки, прочитайте playload, используя эту длину), которая выглядит действительно подверженной ошибкам (!).

дейтаграмма - это спецификация для потока данных. Логически это делит ваш поток на пакеты. Таким образом, лучшей стратегией было бы сначала отправить пакет полезных данных, который указывает длину полезных данных (и размер пакета). Изменить: Конечно, обе стороны потока должны говорить на одном языке протокола / дейтаграммы.

...