Pergunta

Eu tenho um BitSet e quero gravá-lo em um arquivo. Encontrei uma solução para usar um ObjectOutputStream usando o método writeObject.

Olhei o ObjectOutputStream na API java e vi que dá para escrever outras coisas (byte, int, short etc)

Tentei verificar a classe, então tentei escrever um byte em um arquivo usando o código a seguir, mas o resultado me deu um arquivo com 7 bytes em vez de 1 byte

minha pergunta é quais são os primeiros 6 bytes do arquivo?Por que eles estão lá?

minha pergunta é relevante para um BitSet porque não quero começar a gravar muitos dados em um arquivo e perceber que tenho bytes aleatórios inseridos no arquivo sem saber o que são.

aqui está o código:

    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();

Obrigado por qualquer ajuda

Avner

Foi útil?

Solução

Os outros bytes serão informações de tipo.

Basicamente ObjectOutputStream é uma classe usada para gravar objetos Serializable em algum destino (geralmente um arquivo).Faz mais sentido se você pensar em InputObjectStream.Possui um método readObject() nele.Como o Java sabe qual objeto instanciar?Fácil:há informações de tipo lá.

Outras dicas

Você pode estar escrevendo qualquer objetivo para um ObjectOutputStream, portanto, o fluxo contém informações sobre os tipos escritos, bem como os dados necessários para reconstituir o objeto.

Se você souber que o fluxo sempre conterá um bitset, não use um ObjectOutputStream - e se o espaço é um prêmio, converta o BitSet a um conjunto de bytes onde cada bit corresponde um pouco no BitSet, então escreva isso diretamente para o fluxo subjacente (por exemplo, um FileOutputStream como no seu exemplo).

O formato de serialização, como muitos outros, inclui um cabeçalho com informações sobre o número e versão mágica. Quando você usa DataOutput/OutputStream Métodos em ObjectOutputStream são colocados no meio dos dados serializados (Sem informações de tipo). Isso geralmente é feito apenas em writeObject implementações após uma chamada para defaultWriteObject ou uso de putFields.

Se você usar apenas o bitset salvo em Java, a serialização funciona bem. No entanto, é meio irritante se você deseja compartilhar o bitset em plataformas multi. Além da sobrecarga da serialização de Java, o bitset é armazenado em unidades de 8 bytes. Isso pode gerar muita sobrecarga se o seu bitset for pequeno.

Escrevemos essa classe pequena para que possamos extrair matrizes de bytes da Bitset. Dependendo da sua USECASE, pode funcionar melhor do que a serialização do Java para você.

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];
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top