0

保存時にバイトが詰め込まれた Java のバイナリ ファイルを読み取っているため、読み取り時には操作を逆にする必要があります。スタッフィングは、バイトの後に余分なゼロバイトを追加することにありFFます。読み取り時には、そのゼロバイトを破棄する必要があります。ファイルの読み取りにa を使用してDataInputStreamいますが、プログラムのその部分に「生の」読み取りから配列への関数のみを使用していることを見て、大きな違いはありません。

とにかく、これが私がこれまでに得たものです:

public static byte[] unstuff(byte[] stuffed) {
    int bytesToSkip = 0;
    for(int i=0;i<stuffed.length - 1;++i) {
        if(stuffed[i] == 0xFF && stuffed[i+1] == 0) {
            ++bytesToSkip;
        }
    }
    if(bytesToSkip == 0) return stuffed;

    byte unstuffed[] = new byte[stuffed.length - bytesToSkip];
    int j=0;
    for(int i=0;i<stuffed.length - 1;++i) {
        if(stuffed[i] == 0xFF && stuffed[i+1] == 0) {
            ++i;
            continue;
        }
        else {
            unstuffed[j] = stuffed[i];
            ++j;
        }
    }
    return unstuffed;
}

基本的に、関数はスキップするバイト数をカウントし、元のスタッフド配列よりもそのバイト数だけ短い配列を割り当て、それらをコピーして、不要なゼロバイトをスキップします。

問題は、これを行うための他の方法、おそらくもっと滑らかで、より効率的で、より簡単な方法はありますか? バイトを別のコンテナーに入れてから、配列全体をコピーする代わりにそれらを削除する方がうまくいくでしょうか?

4

2 に答える 2

1

最も最適な方法は、元の配列をFF 00スカッシュに使用することです。条件が満たされるたびに、ターゲット インデックスをインクリメントしないでください。完了すると、配列には必要なシーケンスが含まれますが、末尾に余分なバイトがあり、大きすぎる可能性があります。次に、より短い配列にコピーするか、元の配列をそのまま使用しますが、配列へのオフセット + カウントを受け入れるメソッドにそれを渡し、下位のバイト数を渡します。

int target = 0;
for (int i = 1; i < stuffed.length; ++i) {
    if (stuffed[i-1] == 0xFF && stuffed[i] == 0) continue;
    if (i != target) stuffed[target++] = stuffed[i];
}
于 2012-11-18T14:18:37.370 に答える