7

私は BitSet を持っていて、それをファイルに書きたいと思っています - writeObject メソッドを使用して ObjectOutputStream を使用する解決策を見つけました。

Java API の ObjectOutputStream を調べたところ、他のもの (byte、int、short など) を記述できることがわかりました。

クラスをチェックアウトしようとしたので、次のコードを使用してファイルにバイトを書き込もうとしましたが、結果は1バイトではなく7バイトのファイルになります

私の質問は、ファイルの最初の 6 バイトは何ですか? なぜ彼らはそこにいるのですか?

ファイルに大量のデータを書き始めたくないので、私の質問は BitSet に関連しています。

コードは次のとおりです。

    byte[] bt = new byte[]{'A'};
    File outFile = new File("testOut.txt");
    FileOutputStream fos = new FileOutputStream(outFile);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.write(bt);
    oos.close();

助けてくれてありがとう

アヴナー

4

4 に答える 4

2

他のバイトはタイプ情報になります。

基本的に ObjectOutputStream は、Serializable オブジェクトを何らかの宛先 (通常はファイル) に書き込むために使用されるクラスです。InputObjectStream について考えると、より理にかなっています。その上に readObject() メソッドがあります。Javaはインスタンス化するオブジェクトをどのように認識しますか? 簡単: そこに型情報があります。

于 2009-09-04T09:35:17.050 に答える
1

任意のオブジェクトを に書き出すことができるObjectOutputStreamため、ストリームには、書き込まれた型に関する情報と、オブジェクトを再構成するために必要なデータが保持されます。

ストリームに常に BitSet が含まれることがわかっている場合は、- を使用しないでください。スペースが重要な場合は、を、各ビットが のビットに対応するバイトのセットにObjectOutputStream変換し、それを基になる に直接書き込みます。ストリーム(たとえば、あなたの例のように)。BitSetBitSetFileOutputStream

于 2009-09-04T09:34:36.350 に答える
0

シリアライゼーション形式には、他の多くの形式と同様に、マジック ナンバーとバージョン情報を含むヘッダーが含まれています。DataOutput/OutputStreamメソッドを使用するObjectOutputStreamと、シリアル化されたデータの途中に配置されます (型情報なし)。これは通常writeObject、 の呼び出しdefaultWriteObjectまたは使用後の実装でのみ行われputFieldsます。

于 2009-09-04T09:51:12.103 に答える
0

保存された BitSet のみを Java で使用する場合、シリアル化は正常に機能します。ただし、複数のプラットフォーム間でビットセットを共有したい場合は、ちょっと面倒です。Java シリアル化のオーバーヘッドに加えて、BitSet は 8 バイト単位で格納されます。ビットセットが小さい場合、これによりオーバーヘッドが過剰に発生する可能性があります。

BitSet からバイト配列を抽出できるように、この小さなクラスを作成しました。ユースケースによっては、Java シリアライゼーションよりもうまく機能する場合があります。

public class ExportableBitSet extends BitSet {

    private static final long serialVersionUID = 1L;

    public ExportableBitSet() {
        super();
    }

    public ExportableBitSet(int nbits) {
        super(nbits);
    }

    public ExportableBitSet(byte[] bytes) {
        this(bytes == null? 0 : bytes.length*8);        
        for (int i = 0; i < size(); i++) {
            if (isBitOn(i, bytes))
                set(i);
        }
    }

    public byte[] toByteArray()  {

        if (size() == 0)
            return new byte[0];

        // Find highest bit
        int hiBit = -1;
        for (int i = 0; i < size(); i++)  {
            if (get(i))
                hiBit = i;
        }

        int n = (hiBit + 8) / 8;
        byte[] bytes = new byte[n];
        if (n == 0)
            return bytes;

        Arrays.fill(bytes, (byte)0);
        for (int i=0; i<n*8; i++) {
            if (get(i)) 
                setBit(i, bytes);
        }

        return bytes;
    }

    protected static int BIT_MASK[] = 
        {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

    protected static boolean isBitOn(int bit, byte[] bytes) {
        int size = bytes == null ? 0 : bytes.length*8;

        if (bit >= size) 
            return false;

        return (bytes[bit/8] & BIT_MASK[bit%8]) != 0;
    }

    protected static void setBit(int bit, byte[] bytes) {
        int size = bytes == null ? 0 : bytes.length*8;

        if (bit >= size) 
            throw new ArrayIndexOutOfBoundsException("Byte array too small");

        bytes[bit/8] |= BIT_MASK[bit%8];
    }
}
于 2009-09-04T13:31:05.703 に答える