Накладные расходы в Java ObjectOutputStream? - PullRequest
4 голосов
/ 27 февраля 2012

Я озадачен поведением 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();

Длина массива всегда равна 781, хотя я ожидаю, что она будет (1 + 96 + 96) * 4 = 772 байта.Я не могу найти, куда деваются 9 байтов.

Спасибо!

- редактировать: добавлено, если (oos! = Null) {...} для предотвращения NPE

Ответы [ 4 ]

3 голосов
/ 27 февраля 2012

ObjectOutputStream используется для сериализации объектов. Вы не должны делать никаких предположений о том, как хранятся данные.

Если вы хотите хранить только необработанные данные, используйте DataOutputStream .

1 голос
/ 27 февраля 2012

ObjectOutputStream записывает заголовок в начале.

Вы можете исключить этот заголовок, создав подкласс ObjectOutputStream и реализовав writeStreamHeader ().

0 голосов
/ 27 февраля 2012

Поток сериализации Java начинается с 4-байтового заголовка (2-байтовое «магическое число», за которым следует 2-байтовая версия).За заголовком следует последовательность записей данных блока и объектов.Существует два вида ввода данных блоков: «короткий» и «длинный».Короткие блоки имеют 2-байтовые издержки на блок, а длина блока может составлять не более 255 байтов.Длинные блоки имеют 5-байтовую служебную информацию, но могут иметь длину до 4 ГБ.Как долго «длинный» блок может быть на практике, зависит от размера внутренних буферов ObjectOutputStream.

В этом случае у вас есть только одна длинная запись в блоке данных, поэтому накладные расходы, которые вы видите, равны 4байт из заголовка потока и 5 из блока данных, всего 9 байт.

Полная документация находится здесь: http://docs.oracle.com/javase/7/docs/platform/serialization/spec/protocol.html

0 голосов
/ 27 февраля 2012

JavaDoc для ObjectOutputStream сообщает вам:

Примитивные данные, за исключением сериализуемых полей и экстернализуемых данных, записываются в ObjectOutputStream в записях блочных данных.Блок данных записи состоит из заголовка и данных.Заголовок данных блока состоит из маркера и количества байтов, следующих за заголовком.Последовательные примитивные записи данных объединяются в одну запись блочных данных.Коэффициент блокировки, используемый для записи данных блока, будет 1024 байта.Каждая запись блочных данных будет заполнена до 1024 байтов или будет записана всякий раз, когда происходит завершение режима блочных данных.Вызовы методов ObjectOutputStream writeObject, defaultWriteObject и writeFields первоначально завершают любую существующую запись данных блока.

Таким образом, блокирующая вещь может быть вашими недостающими издержками.

...