什么相当于“ByteBuffer.flip”& .NET中的“ByteBuffer.slice”?

时间:2009-08-12 15:33:29

标签: c# memorystream slice flip bytebuffer

我需要将代码从Java移植到C#。在Java代码中,使用了方法“ByteBuffer.flip()”和“ByteBuffer.slice”,我不知道如何翻译它。

我已经阅读了这个问题(An equivalent of javax.nio.Buffer.flip() in c#),但是虽然给出了答案,但我无法想出如何应用它。根据Tom Hawtin的说法,我应该在底层数组中“将限制设置为当前位置,然后将位置设置为零”。我不确定如何改变这些价值观。 (如果你能解释一下基础逻辑,它会对我有很大的帮助:)。

对于ByteBuffer.slice,我不知道如何翻译它。

编辑:如果实际代码更清楚,我会发布:

爪哇:

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

谢谢!

编辑:根据Java文档将b.BaseStream.SetLength(b.BaseStream.Length);更改为b.BaseStream.SetLength(b.BaseStream.Position);

2 个答案:

答案 0 :(得分:1)

(有关java的调用,请参阅http://java.sun.com/javase/6/docs/api/java/nio/ByteBuffer.html#slice%28%29http://java.sun.com/javase/6/docs/api/java/nio/Buffer.html#flip%28%29

翻转是重置缓冲区的快捷方式。所以举个例子 (伪代码)

void flip()
{
   Length = currentPos;
   currentPos = 0;
}

允许您快速设置您可能刚刚写入的缓冲区,以便从头开始阅读。

<强>更新 Splice有点棘手,因为要求“对此缓冲区内容的更改将在新缓冲区中可见,反之亦然;两个缓冲区的位置,限制和标记值将是独立的”。不幸的是,没有共享缓冲区的概念(我知道 - 总是使用数组,详见下文),而不是自己创建类。你能做的最接近的事是:

旧代码:

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[] b = &buff[buffPos];

...然而,这需要启用不安全的操作,并且由于垃圾收集器和我避免使用“不安全”功能,我无法保证其安全性。

除此之外,还有自己的ByteBuffer类。

答案 1 :(得分:1)

未经测试,但如果我正确理解了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);
    }
}