3

コードを Java から C# に移植する必要があります。Javaコードでは「ByteBuffer.flip()」と「ByteBuffer.slice」というメソッドが使われているのですが、これをどう訳せばいいのかわかりません。

私はこの質問を読みました( c# の javax.nio.Buffer.flip() に相当します)が、答えは示されていますが、それを適用する方法がわかりません。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);

4

2 に答える 2

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);
    }
}
于 2009-08-12T16:28:31.973 に答える
1

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

おそらくちょうど書き込んだばかりのバッファを、最初から読み取るためにすばやくセットアップできます。

更新: Splice は、「このバッファーのコンテンツへの変更は新しいバッファーで表示され、その逆も同様です。2 つのバッファーの位置、制限、およびマークの値は独立している」という要件があるため、少しトリッキーです。残念ながら、独自のクラスを作成しない限り、バッファーの共有部分の概念はありません (私が知っている - 常に配列を使用しています)。あなたができる最も近いことはこれです:

古いコード:

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 クラスを作成しています。

于 2009-08-12T15:48:50.323 に答える