2012-02-21 7 views
1

私は現在、自分のコードにcom.google.common.io.ByteArrayDataInputを使用しています。私が書いているのは、バイナリファイルのローダーの一種です。残念ながら、ByteArrayDataInputは、内部バイト配列に何バイト残っているかの情報を提供しません。そのような情報を提供するこのクラスの代替手段はありますか?私はcom.google.common.io.ByteArrayDataInputのための私自身のラッパークラスを書くことができますが、私はそれを避けたいと思います。com.google.common.io.ByteArrayDataInputの代替ですか?

EDIT

問題は私のcom.google.common.io.ByteArrayDataInputインスタンスへの参照は、メソッドの連鎖を通じて非常に深く渡されていることです。それは次のようになります。

loadA(ByteArrayDataInput in)は等々loadC(in);を呼び出し、loadB(in)を起動します。..

LOADXのすべての

は()メソッド inから何かを読み込みます。そして、私は loadC()ByteArrayDataInput.readFully()メソッドを呼び出したいと思います。そのレベルで何バイト読み込むかを確認したいと思います。このクラスで達成するには、bytesLeft情報をすべての loadX()メソッドに渡す必要があります。

+0

すでに読み込まれたバイト数を数えれば、ファイルサイズは分かります。あなたが使っている実装クラスはどれですか? – vulkanino

+0

@vulkanino:私の編集を参照してください – Lukasz

+0

ここで助けてください - 例外をスローしない以外、ByteArrayDataInputは、ByteArrayInputStreamをラッピングするObjectInputStreamが提供していないものを提供していますか?たぶん私は朝のコーヒーが必要なだけかもしれませんが、意味のある違いはありません。 – cutchin

答えて

0

Guava ByteArrayDataInputWrapperの独自のラッパークラスを用意する必要がありました。 新しいメソッドgetAvailable()を追加し、読み込み済みのバイト数を返します。

public class ByteArrayDataInputWrapper implements ByteArrayDataInput { 

    private static final int INT_LENGTH = 4; 
    private static final int FLOAT_LENGTH = 4; 
    private static final int LONG_LENGTH = 8; 
    private static final int DOUBLE_LENGTH = 8; 

    private ByteArrayDataInput in; 
    private int available; 

    public ByteArrayDataInputWrapper(byte[] binary) { 
     if (binary != null) { 
      in = ByteStreams.newDataInput(binary); 
      available = binary.length; 
     } 
    } 

    public int getAvailable() { 
     return available; 
    } 

    @Override 
    public void readFully(byte[] b) { 
     in.readFully(b); 
     available -= b.length; 
    } 

    @Override 
    public void readFully(byte[] b, int off, int len) { 
     in.readFully(b, off, len); 
     available -= len; 
    } 

    @Override 
    public int skipBytes(int n) { 
     int skipped = in.skipBytes(n); 
     available -= skipped; 
     return skipped; 
    } 

    @Override 
    public boolean readBoolean() { 
     boolean result = in.readBoolean(); 
     available--; 
     return result; 
    } 

    @Override 
    public byte readByte() { 
     byte result = in.readByte(); 
     available--; 
     return result; 
    } 

    @Override 
    public int readUnsignedByte() { 
     int result = in.readUnsignedByte(); 
     available--; 
     return result; 
    } 

    @Override 
    public short readShort() { 
     short result = in.readShort(); 
     available -= 2; 
     return result; 
    } 

    @Override 
    public int readUnsignedShort() { 
     int result = in.readUnsignedShort(); 
     available -= 2; 
     return result; 
    } 

    @Override 
    public char readChar() { 
     char result = in.readChar(); 
     available -= 2; 
     return result; 
    } 

    @Override 
    public int readInt() { 
     int result = in.readInt(); 
     available -= INT_LENGTH; 
     return result; 
    } 

    @Override 
    public long readLong() { 
     long result = in.readLong(); 
     available -= LONG_LENGTH; 
     return result; 
    } 

    @Override 
    public float readFloat() { 
     float result = in.readFloat(); 
     available -= FLOAT_LENGTH; 
     return result; 
    } 

    @Override 
    public double readDouble() { 
     double result = in.readDouble(); 
     available -= DOUBLE_LENGTH; 
     return result; 
    } 

    @Override 
    public String readLine() { 
     String result = in.readLine(); 
     if (result != null) { 
      available -= result.length(); 
     } 
     return result; 
    } 

    @Override 
    public String readUTF() { 
     String result = in.readUTF(); 
     if (result != null) { 
      available -= result.length(); 
     } 
     return result; 
    } 

} 
2

ByteArrayInputStreamの利用可能なメソッドは、sourceに従って配列に残っているバイト数を返します。 ObjectInputStreamでそれをラップすると、ほぼ同じ機能を提供するように見えます。 ObjectInputStreamのavailable()メソッドは、処理を行わずに、基礎となる入力ストリームからavailable()を返します。

+0

あなたのアプローチには1つの問題があります。 ObjectInputStreamはObjectOutputStreamと一緒に行かなければならず、私は自分のコードでそのようなシリアル化をしたくありません。私は単純にバイトの生の配列を取得しています。 – Lukasz

+0

実際には、DataInputStreamもほとんど同じメソッドを持ち、シリアル化に関連するものと結びついていません。あなたがあなたの文字列にヌルを持っているならば、ほとんどの場合関連性のある "modified UTF-8"を使います。 Guavaライブラリと同じであるかどうかはわかりません。 – cutchin

+0

さて、ObjectInputStreamは私の問題を解決すると本当に思っていましたが、私は他の問題に遭遇しました:http://stackoverflow.com/questions/9381521/java-io-streamcorruptedexception-invalid-stream-header – Lukasz

関連する問題