Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java ObjectOutputStream中的开销?_Java_Serialization_Bytearray_Objectoutputstream - Fatal编程技术网

java ObjectOutputStream中的开销?

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

我对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 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安全编码标准”我不得不反复指出代码中的缺陷。保持简单。/哦,不要害怕在十六进制编辑器/查看器中查看原始序列化数据!谢谢,这正是我需要的。