написание BitSet в файл в Java
У меня есть битовый набор и я хочу записать его в файл - я наткнулся на решение использовать ObjectOutputStream с помощью метода writeObject.
Я посмотрел на ObjectOutputStream в Java API и увидел, что вы можете писать другие вещи (byte, int, short etc)
Я попытался проверить класс, поэтому я попытался написать байт в файл, используя следующий код, но результат дает мне файл с 7 байтами вместо 1 байта
мой вопрос в том, что первые 6 байты в файле? почему они там?
мой вопрос относится к битовому набору, потому что я не хочу начинать писать много данных в файл и понимать, что у меня есть случайные байты, вставленные в файл, не зная, что они такое.
вот код:
    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 ответов
другие байты будут информацией о типе.
в основном ObjectOutputStream-это класс, используемый для записи Сериализуемых объектов в некоторый пункт назначения (обычно файл). Это имеет больше смысла, если вы думаете о InputObjectStream. На нем есть метод readObject (). Как Java знает, какой объект для создания экземпляра? Легко: там есть информация о типе.
вы можете записывать любые объекты в ObjectOutputStream, таким образом, поток содержит информацию о типах, записанных, а также данные, необходимые для восстановления объекта.
если вы знаете, что поток всегда будет содержать BitSet, не используйте ObjectOutputStream - и если пространство является премией, то преобразуйте BitSet в набор байт, где каждый бит соответствует биту в BitSet, затем напишите это непосредственно в базовый поток (например, a FileOutputStream как в вашем примере).
формат сериализации, как и многие другие, включает заголовок с магическим номером и информацией о версии. Когда вы используете DataOutput/OutputStream методы on ObjectOutputStream помещаются в середине сериализованных данных (без информации о типе). Обычно это делается только в writeObject реализации после вызова defaultWriteObject или использовать putFields. 
Если вы используете только сохраненный битовый набор в Java, сериализация работает нормально. Тем не менее, это раздражает, если вы хотите поделиться битовым набором на нескольких платформах. Помимо накладных расходов на сериализацию Java, битовый набор хранится в единицах 8 байт. Это может создать слишком много накладных расходов, если ваш набор бит мал.
мы написали этот небольшой класс, чтобы мы могли экстрагировать байтовые массивы из BitSet. В зависимости от вашего usecase, это может работать лучше, чем сериализация 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];
    }
}
