在.NET中,与"ByteBuffer.flip"和"ByteBuffer.slice"等效的方法是什么?

3
我需要将Java代码移植到C#中。在Java代码中,使用了"ByteBuffer.flip()"和"ByteBuffer.slice"方法,但我不知道如何翻译这些方法。
我已经阅读了这篇问题(An equivalent of javax.nio.Buffer.flip() in c#),尽管有答案,但我无法理解如何应用它。根据Tom Hawtin的说法,我应该在底层数组中“将限制设置为当前位置,然后将位置设置为零”。我不确定如何更改这些值。(如果您能解释其中的逻辑,那会对我很有帮助:)
至于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

谢谢你!

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


快速提醒:这些等价物将在.NET中,而不是在C#中。 - John Saunders
你在 ByteBuffer 中使用了哪种类型的结构?是 List<byte>、byte[] 还是其他的? - SwDevMan81
我正在使用一个byte[]结构。 - Lazlo
2个回答

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

Flip是重置缓冲区的快速方法。例如(伪代码)

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循环(for i = bStart;...)到索引(newList [i + bStart] ...)
另一个选择是改用Byte[]数组,并执行以下操作:
Byte[] b = &buff[buffPos];

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

除此之外,总是可以自己制作自己的ByteBuffer类。


谢谢您的回答。您能否再次阅读帖子,包括代码示例?我认为我在“flip()”等价物上做得很正确,如果我错了,请纠正我。现在我将尝试实现您的slice()方法。我会发布它并希望它很好。 :) - Lazlo
我已经修改了我的翻转方法以适应你的方法。我认为现在更合适了。我还在等待你的切片方法。感谢你的帮助。 :) - Lazlo

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);
    }
}

我可能会尝试创建自己的 ByteBuffer 类,但确实很难做到。 - Lazlo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接