Что эквивалентно “ByteBuffer.flip“ и "ByteBuffer.slice” в .NET?
-
13-09-2019 - |
Вопрос
Мне нужно перенести код с Java на C #.В коде Java используются методы "ByteBuffer.flip()" и "ByteBuffer.slice", и я не знаю, как это перевести.
Я прочитал этот вопрос (Эквивалент javax.nio.Buffer.flip() в c#), но хотя ответ дан, я не могу понять, как его применить.По словам Тома Хотина, я должен "Установить ограничение на текущую позицию, а затем установить позицию равной нулю" в базовом массиве.Я не уверен в том, как изменить эти значения.(Если бы вы могли объяснить лежащую в основе логику, это бы мне очень помогло :)
Что касается ByteBuffer.slice, я понятия не имею, как его перевести.
Редактировать:Если с реальным кодом будет понятнее, я опубликую его:
Java:
ByteBuffer buff;
buff.putShort((short) 0);
buff.put(customArray);
buff.flip();
buff.putShort((short) 0);
ByteBuffer b = buff.slice();
short size = (short) (customFunction(b) + 2);
buff.putShort(0, size);
buff.position(0).limit(size);
Пока что мой перевод на C#.NET:
BinaryWriter b = new BinaryWriter(); //ByteBuffer buff;
b.Write((short)0); // buff.putShort((short) 0);
b.Write(paramStream.ToArray()); // buff.put(customArray);
b.BaseStream.SetLength(b.BaseStream.Position); // buff.flip; (not sure)
b.BaseStream.Position = 0; // buff.flip; too (not sure)
b.Write((short)0); // buff.putShort((short) 0)
??? // ByteBuffer b = buff.slice();
// Not done but I can do it, short size = (short) (customFunction(b) + 2);
??? // How do I write at a particular position?
??? // buff.position(0).limit(size); I don't know how to do this
Спасибо!
Редактировать:Измененный b.BaseStream.SetLength(b.BaseStream.Length);
Для b.BaseStream.SetLength(b.BaseStream.Position);
, основанный на документах Java.
Решение
(Смотри, смотри http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#slice%28%29 и http://java.sun.com/javase/6/docs/api/java/nio/Buffer.html#flip%28%29 для вызовов java)
Flip - это быстрый способ сброса буфера.Так, например (псевдокод)
void flip()
{
Length = currentPos;
currentPos = 0;
}
Позволяет вам быстро настроить буфер, в который вы, предположительно, только что записали, для чтения с самого начала.
Обновить: Сращивание немного сложнее из-за требования, что "Изменения содержимого этого буфера будут видны в новом буфере, и наоборот;значения положения, предела и метки двух буферов будут независимыми ".К сожалению, не существует концепции общей части буфера (о которой я знаю - всегда используются массивы, подробно описанные ниже) без создания вашего собственного класса.Самое близкое, что вы могли бы сделать, это это:
Старый Код:
ByteBuffer b = buff.slice();
Новый код (предполагается наличие списка)
List<Byte> b= buff;
int bStart = buffPos; // buffPos is your way of tracking your mark
недостатком приведенного выше кода является то, что у c # нет способа сохранить новую начальную точку нового буфера и по-прежнему совместно использовать ее.Вам придется вручную использовать новую начальную точку всякий раз, когда вы что-либо делаете, от циклов for (для i=bStart; ...) до индексации (newList[i + bStart] ...)
Другой ваш вариант - вместо этого использовать массивы Byte [] и сделать что-то вроде этого:
Byte[] b = &buff[buffPos];
...однако для этого требуется включить небезопасные операции, и я не могу ручаться за их безопасность из-за сборщика мусора и моего избегания "небезопасных" функций.
Помимо этого, вы всегда создаете свой собственный класс ByteBuffer.
Другие советы
Непроверено, но если я правильно понимаю биты Java, это даст вам представление о том, как реализовать.
public class ByteBuffer {
private int _Position;
private int _Capacity;
private byte[] _Buffer;
private int _Start;
private ByteBuffer(int capacity, int position, int start, byte[] buffer) {
_Capacity = capacity;
_Position = position;
_Start = start;
_Buffer = buffer;
}
public ByteBuffer(int capacity) : this(capacity, 0 , 0, new byte[capacity]) {
}
public void Write(byte item) {
if (_Position >= _Capacity) {
throw new InvalidOperationException();
}
_Buffer[_Start + _Position++] = item;
}
public byte Read() {
if (_Position >= _Capacity) {
throw new InvalidOperationException();
}
return _Buffer[_Start + _Position++];
}
public void Flip() {
_Capacity = _Position;
_Position = _Start;
}
public ByteBuffer Slice() {
return new ByteBuffer(_Capacity-_Position, 0, _Position, _Buffer);
}
}