用java将BitSet写入文件

发布于 2024-08-04 01:07:54 字数 609 浏览 10 评论 0原文

我有一个 BitSet 并想将其写入文件 - 我遇到了一个使用 writeObject 方法使用 ObjectOutputStream 的解决方案。

我查看了java API中的ObjectOutputStream,发现您可以编写其他内容(字节,整数,短等)

我尝试检查该类,因此我尝试使用以下代码将字节写入文件,但结果给出我的文件有 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();

感谢您的帮助

Avner

I have a BitSet and want to write it to a file- I came across a solution to use a ObjectOutputStream using the writeObject method.

I looked at the ObjectOutputStream in the java API and saw that you can write other things (byte, int, short etc)

I tried to check out the class so I tried to write a byte to a file using the following code but the result gives me a file with 7 bytes instead of 1 byte

my question is what are the first 6 bytes in the file? why are they there?

my question is relevant to a BitSet because i don't want to start writing lots of data to a file and realize I have random bytes inserted in the file without knowing what they are.

here is the code:

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

thanks for any help

Avner

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

柳絮泡泡 2024-08-11 01:07:54

其他字节将是类型信息。

基本上,ObjectOutputStream 是一个用于将可序列化对象写入某个目的地(通常是文件)的类。如果你考虑一下 InputObjectStream 就更有意义了。它有一个 readObject() 方法。 Java 如何知道要实例化什么对象?简单:里面有类型信息。

The other bytes will be type information.

Basically ObjectOutputStream is a class used to write Serializable objects to some destination (usually a file). It makes more sense if you think about InputObjectStream. It has a readObject() method on it. How does Java know what Object to instantiate? Easy: there is type information in there.

⒈起吃苦の倖褔 2024-08-11 01:07:54

您可以将任何对象写入ObjectOutputStream,因此该流保存有关写入的类型以及重构对象所需的数据的信息。

如果您知道流将始终包含 BitSet,请不要使用 ObjectOutputStream - 如果空间非常宝贵,则将 BitSet 转换为一组字节,其中每个位对应于 BitSet 中的一个位,然后将其直接写入底层流(例如,如示例中的 FileOutputStream)。

You could be writing any objects out to an ObjectOutputStream, so the stream holds information about the types written as well as the data needed to reconstitute the object.

If you know that the stream will always contain a BitSet, don't use an ObjectOutputStream - and if space is a premium, then convert the BitSet to a set of bytes where each bit corresponds to a bit in the BitSet, then write that directly to the underlying stream (e.g. a FileOutputStream as in your example).

驱逐舰岛风号 2024-08-11 01:07:54

与许多其他格式一样,序列化格式包括带有幻数和版本信息的标头。当您使用 ObjectOutputStream 上的 DataOutput/OutputStream 方法时,它们被放置在序列化数据的中间(没有类型信息)。这通常仅在调用 defaultWriteObject 或使用 putFields 后在 writeObject 实现中完成。

The serialisation format, like many others, includes a header with magic number and version information. When you use DataOutput/OutputStream methods on ObjectOutputStream are placed in the middle of the serialised data (with no type information). This is typically only done in writeObject implementations after a call to defaultWriteObject or use of putFields.

风向决定发型 2024-08-11 01:07:54

如果你只使用Java中保存的BitSet,序列化工作正常。但是,如果您想跨多个平台共享位集,这有点烦人。除了 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];
    }
}

If you only use the saved BitSet in Java, the serialization works fine. However, it's kind of annoying if you want share the bitset across multi platforms. Besides the overhead of Java serialization, the BitSet is stored in units of 8-bytes. This can generate too much overhead if your bitset is small.

We wrote this small class so we can exract byte arrays from BitSet. Depending on your usecase, it might work better than Java serialization for you.

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];
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文