簡體   English   中英

將BitSet寫入java中的文件

[英]writing a BitSet to a file in java

我有一個BitSet並希望將其寫入文件 - 我遇到了使用writeObject方法使用ObjectOutputStream的解決方案。

我查看了java API中的ObjectOutputStream,看到你可以編寫其他東西(byte,int,short等)

我試着檢查一下這個類,所以我嘗試使用以下代碼將一個字節寫入文件,但結果給了我一個7字節而不是1字節的文件

我的問題是文件中的前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();

謝謝你的幫助

阿夫納

其他字節將是類型信息。

基本上,ObjectOutputStream是一個用於將Serializable對象寫入某個目標(通常是文件)的類。 如果你考慮InputObjectStream,它會更有意義。 它上面有一個readObject()方法。 Java如何知道要實例化的Object? 簡單:那里有類型信息。

您可以將任何對象寫入ObjectOutputStream ,因此該流包含有關所寫類型的信息以及重構該對象所需的數據。

如果您知道流將始終包含BitSet,請不要使用ObjectOutputStream - 如果空間是溢價,則將BitSet轉換為一組字節,其中每個位對應於BitSet一個位,然后直接寫入到底層流(例如,在您的示例中為FileOutputStream )。

與許多其他格式一樣,序列化格式包括帶有幻數和版本信息的標題。 當您使用DataOutput / OutputStream方法時, ObjectOutputStream被放置在序列化數據的中間( 沒有類型信息 )。 這通常僅在調用defaultWriteObject或使用putFields之后在writeObject實現中putFields

如果您只使用Java中保存的BitSet,序列化工作正常。 但是,如果你想在多平台上共享bitset,那就太煩人了。 除了Java序列化的開銷之外,BitSet以8字節為單位存儲。 如果你的bitset很小,這會產生太多的開銷。

我們編寫了這個小類,因此我們可以從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];
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM