我有一个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();
感谢您的帮助
阿夫纳
答案 0 :(得分:2)
其他字节将是类型信息。
基本上,ObjectOutputStream是一个用于将Serializable对象写入某个目标(通常是文件)的类。如果你考虑InputObjectStream,它会更有意义。它上面有一个readObject()方法。 Java如何知道要实例化的Object?简单:那里有类型信息。
答案 1 :(得分:1)
您可以将任何对象写入ObjectOutputStream
,因此该流包含有关所写类型的信息以及重构对象所需的数据。
如果您知道流将始终包含BitSet,请不要使用ObjectOutputStream
- 如果空间是溢价,则将BitSet
转换为每个位对应的一组字节在BitSet
中稍微写一下,然后将其直接写入底层流(例如,如示例中的FileOutputStream
)。
答案 2 :(得分:0)
序列化格式与许多其他格式一样,包括带有幻数和版本信息的标题。当您使用DataOutput
上的OutputStream
/ ObjectOutputStream
方法放置在序列化数据(没有类型信息)的中间时。这通常仅在调用writeObject
或使用defaultWriteObject
后在putFields
实施中完成。
答案 3 :(得分:0)
如果您只使用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];
}
}