java ObjectOutputStream中的开销?
我对ObjectOutputStream的行为感到困惑。在写入数据时,它似乎有9个字节的开销。考虑下面的代码:java ObjectOutputStream中的开销?,java,serialization,bytearray,objectoutputstream,Java,Serialization,Bytearray,Objectoutputstream,我对ObjectOutputStream的行为感到困惑。在写入数据时,它似乎有9个字节的开销。考虑下面的代码: float[] speeds = new float[96]; float[] flows = new float[96]; //.. do some stuff here to fill the arrays with data ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream
float[] speeds = new float[96];
float[] flows = new float[96];
//.. do some stuff here to fill the arrays with data
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos=null;
try {
oos = new ObjectOutputStream(baos);
oos.writeInt(speeds.length);
for(int i=0;i<speeds.length;i++) {
oos.writeFloat(speeds[i]);
}
for(int i=0;i<flows.length;i++) {
oos.writeFloat(flows[i]);
}
oos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(oos!=null) {
oos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
byte[] array = baos.toByteArray();
float[]速度=新的float[96];
浮动[]流量=新浮动[96];
//.. 在这里做一些事情,用数据填充数组
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
ObjectOutputStream oos=null;
试一试{
oos=新对象输出流(BAS);
oos.writeInt(速度、长度);
对于(int i=0;i,ObjectOutputStream在开头写入一个头
通过将ObjectOutputStream子类化并实现writeStreamHeader(),可以消除此标头。ObjectOutputStream的JavaDoc告诉您:
基本数据(不包括可序列化字段和可外部化数据)写入块数据记录中的ObjectOutputStream。块数据记录由标头和数据组成。块数据标头由标记和标头后面的字节数组成。连续的基本数据写入合并为一个块数据记录。块数据记录使用的阻塞因子将为1024字节。每个块数据记录将填充到1024字节,或者在块数据模式终止时写入。对ObjectOutputStream方法writeObject、defaultWriteObject和writeFields的调用最初会终止任何现有的块数据记录
因此,阻塞内容可能是您缺少的开销。用于序列化对象。您不应该假设数据是如何存储的
如果您想只存储原始数据,请改用。Java的序列化流以4字节的头开始(2字节的“幻数”后跟2字节版本)。头后面是一系列块数据和对象项。有两种块数据项:“短”和“长”短块的每个块的开销为2字节,且块的长度最多为255字节。长块的开销为5字节,但其长度最多可达4 GB。实际上,“长”块的长度取决于ObjectOutputStream
的内部缓冲区的大小
在本例中,您只有一个长数据块条目,因此您看到的开销是来自流头的4个字节和来自数据块的5个字节,总共9个字节
您可以在这里找到完整的文档:像大多数文件格式一样,有一个头和版本号。如果您只是在编写原语,ObjectOutputStream
不是一个很好的解决方案。/另外acquire();try{use();}最终{release();}
或者在JavaSE7中try(Type resource=acquire()){use();}
。你有一个潜在的NPE,以及糟糕的错误处理。嗨,汤姆,关于空指针你是对的。在代码中修复了它。NPE只是笨拙的资源处理的副作用。一旦你决定不使用清晰的代码,就很容易出错。即使是“CERT-Oracle Java安全编码标准”我不得不反复指出代码中的缺陷。保持简单。/哦,不要害怕在十六进制编辑器/查看器中查看原始序列化数据!谢谢,这正是我需要的。