Здравствуйте, Аноним, Вы писали:
А>как представвить обьект в в качестве масива байт? Насколько я понял, серриализация сохраняет также мета-данные, поэтому для этой задачи не катит(
1. Для чего именно Вам нужно представить объект как массив байт, что метаданные могут помешать?
2. Что-то сомневаюсь насчет законности такого преобразования любого объекта в массив байт на С++.
Вижу изменение типа указателя на объект на указатель на массив char. А что будет при выходе за границы массива?
как представвить обьект в в качестве масива байт? Насколько я понял, серриализация сохраняет также мета-данные, поэтому для этой задачи не катит(
на си++ это делается так:
char* pBuffer = (char*)&some_object;
как это делается в яве?
Re[2]: Обьект в масив байт
От:
Аноним
Дата:
21.08.09 13:49
Оценка:
Здравствуйте, von Zeppelin, Вы писали:
VZ>1. Для чего именно Вам нужно представить объект как массив байт, что метаданные могут помешать?
Надо его передавать по сети, а удалённый клиент его точно не дессереализует.
VZ>2. Что-то сомневаюсь насчет законности такого преобразования любого объекта в массив байт на С++. VZ> Вижу изменение типа указателя на объект на указатель на массив char. А что будет при выходе за границы массива?
тоже что и обычно, когда выходиш за границы масива...
Здравствуйте, Аноним, Вы писали: А>как представвить обьект в в качестве масива байт? Насколько я понял, серриализация сохраняет также мета-данные, поэтому для этой задачи не катит( А>на си++ это делается так: А>
А>char* pBuffer = (char*)&some_object;
А>
А>как это делается в яве?
99.99% программистов Java всё же будут использовать сериализацию Кстати, на С++ тоже не всё так просто. Просто получить указатель на объект — это ничего не значит. Это на структуру указатель, при её известной длине, имеет смысл как указатель на массив байт, а вот класс уже так не сохранить, вернее — не восстановить потом, не найти где что лежит, по крайней мере. Да и длина экземпляра класса вещь неопределённая А возможные ссылки на другие структуры и классы? То есть, проблема требует конкретного решения.
Я в Java обычно использую класс ByteBuffer для укладки в массив байт всех полей нужных мне данных из класса. В ByteBuffer есть методы для записи/чтения всех примитивных типов данных. А как понятно, данные любого класса можно свести к сумме примитивных полей. Получается, при аккуратном подходе, очень быстрая и компактная упаковка. Конечно, она не универсальна. Для каждого нового класса придётся написать/дописать свой метод упаковки/распаковки. Но иногда овчинка стоит выделки. Главное при чтении данных через ByteBuffer знать, какой ByteOrder использовался при запаковке
Здравствуйте, Аноним, Вы писали:
А>как представвить обьект в в качестве масива байт? Насколько я понял, серриализация сохраняет также мета-данные, поэтому для этой задачи не катит(
А>на си++ это делается так: А>
А>char* pBuffer = (char*)&some_object;
А>
А>как это делается в яве?
Преобразование объекта в масив байт это скорее средство решения какой-то другой задачи.
Для задач типа, переслать объект по сети, или сохранить на диск — сериализация самое оно.
Озвучте Вашу основную задачу.
Касательно приведёного кода на С++, то он некорректен. Если мне не изменяет мой склероз, то
во-первых такое преобразование зависит от реализации. Из этого следует
во-вторых при множественном наследовании, в типичной реализации, g++ например, в зависимости от того, через какой указатель к объекту доступаемся pBuffer будет иметь разные значения
(в некоторых реализациях Вы кроме собственно полей объекта увидите ещё и указатели на таблицы виртуальных функции)
в-третьих, иногда (зависит от реализации) в случае наличия виртуальных функций, кроме собственно полей объекта в "массив байт" попадут ещё и указатели на таблицы виртуальных функций (== метаданные).
Re[2]: Обьект в масив байт
От:
Аноним
Дата:
21.08.09 14:13
Оценка:
KRA>Преобразование объекта в масив байт это скорее средство решения какой-то другой задачи. KRA>Для задач типа, переслать объект по сети, или сохранить на диск — сериализация самое оно. KRA>Озвучте Вашу основную задачу.
KRA>Касательно приведёного кода на С++, то он некорректен. Если мне не изменяет мой склероз, то KRA>во-первых такое преобразование зависит от реализации. Из этого следует KRA>во-вторых при множественном наследовании, в типичной реализации, g++ например, в зависимости от того, через какой указатель к объекту доступаемся pBuffer будет иметь разные значения KRA>(в некоторых реализациях Вы кроме собственно полей объекта увидите ещё и указатели на таблицы виртуальных функции) KRA>в-третьих, иногда (зависит от реализации) в случае наличия виртуальных функций, кроме собственно полей объекта в "массив байт" попадут ещё и указатели на таблицы виртуальных функций (== метаданные).
Собственно задача, состоит в реализации бинарного протокола обмена между сервеным приложением и неким сетевым оборудованием. Мне, почемуто, показалось, что представить заголовок пакета, в качестве класса (структуры для си++), сулит определёнными удобствами при его заполнении.
Что касается приведённого примера, то под "some_object", конечно-же, следует понимать экземпляр некой структуры состоящей, исключительно, из полей простых типов, с учётом правильного выравнивания, и известного размера. И вобще, пример приведён исключительно для наглядной демонстрации стоящей перед мной задачи.
Здравствуйте, Аноним, Вы писали:
А>Собственно задача, состоит в реализации бинарного протокола обмена между сервеным приложением и неким сетевым оборудованием. Мне, почемуто, показалось, что представить заголовок пакета, в качестве класса (структуры для си++), сулит определёнными удобствами при его заполнении.
Здравствуйте, Аноним, Вы писали:
А>как представвить обьект в в качестве масива байт? Насколько я понял, серриализация сохраняет также мета-данные, поэтому для этой задачи не катит(
А>на си++ это делается так: А>
А>char* pBuffer = (char*)&some_object;
А>
А>как это делается в яве?
java.io.Externalizable.
Более эффективное решение — собственный маршаллинг в nio buffers.
Главное, про что помнить — byte-ordering и разрядность удаленной системы.
Здравствуйте, von Zeppelin, Вы писали:
VZ>Здравствуйте, Географ, Вы писали: Г>>Я в Java обычно использую класс ByteBuffer для укладки в массив байт всех полей нужных мне данных из класса VZ>DataInputStream, DataOutputStream еще есть ByteBuffer это все же для работы с NIO.
Согласен. Я не упомянул, что работаю обычно с RandomAccessFile напрямую, позиционируясь на упакованный объект как массив байт. И здесь ByteBuffer уместнее, позволяя ещё и буферизовать поточнее. Заказал, скажем, ByteBuffer длиной 16 килобайт и уже ощутимая прибавка в скорости. При этом возможно перепрыгнуть и назад при необходимости. Но согласен, в общем случае DataInputStream более привычен именно для Java стиля программирования. Просто я не так давно на Java перешёл, года 2 реальных, а был до этого в основном Object Pascal(Delphi), C++ и C#. Отсюда и подсознательное стредмление к низкоуровневости Но я не осуждаю, а даже приветствую Java стиль Он выигрывыает в общности, хотя и может проиграть в частностях. Но это уже философский вопрос.
Кстати, в одной из разработок обнаружил парадокс — если хранить большое количество небольших объектов (как байт-массивы) в памяти (ГИС система), их обработка при выводе (через Swing) занимает не меньше времени, чем считывание нужного набора из файлов и распаковка на лету каждый раз. При этом могу (и делаю так ) использовать только один экземпляр объекта, который себя перестраивает, наращивая нужные буфера по мере необходимости, если следующий объект превосходит по размеру (количество точек в полигоне, например) предыдущий. И потребная память не растёт, т.е. приложение становится хорошо масштабируемым. Так, можно открывать одновременно 1, 2, 3, 5... n карт и память НЕ растёт. Как была 50 мегабайт физической и 50 мегабайт виртуальной, так и остаётся. При этом отдельные файлы занимают на диске от 20 до 50 мегайбайт, а в памяти намного больше.
Re: Обьект в масив байт
От:
Аноним
Дата:
26.08.09 11:32
Оценка:
Здравствуйте, Аноним, Вы писали:
А>как представвить обьект в в качестве масива байт? Насколько я понял, серриализация сохраняет также мета-данные, поэтому для этой задачи не катит(
А>на си++ это делается так: А>
А>char* pBuffer = (char*)&some_object;
А>
А>как это делается в яве?
Смотри в сторону интерфейса java.io.Externalizable