Kako napraviti sopstveni protokol serializacije?
sobes.tech АИ
Одговор од АИ
Да бисте креирали сопствени протокол за серијализацију у Јави, потребно је да одредите формат података и имплементирате логику читања/писања.
-
Одредите формат података: Одлучите како ће објекти бити представљени у бајт формату. Ово може бити бинарни формат (компактнији) или текстуални (лакши за читање). На пример, можете користити префикс за дужину пре поља.
-
Реализујте читање и писање:
- Креирајте класу
MySerializer(или сличну), која ће садржати методеserializeиdeserialize. - Метод
serializeће примати објекат иOutputStream, записујући бајтове објекта у поток у складу са дефинисаним форматом. - Метод
deserializeће приматиInputStreamи враћати објекат из бајтова.
- Креирајте класу
-
Обележавање класа за серијализацију: Класама које треба да буду серијализоване треба обезбедити механизам за интеракцију са серијализатором. Ово може бити:
- Реализација интерфејса
Serializable(али тада ће се користити стандардни механизам Јаве). - Одређивање корисничких метода
writeObjectиreadObject(сличноreadObjectиwriteObjectза стандардну серијализацију, али са сопственом сигнатуром). - Коришћење анотација за означавање поља која треба да буду серијализована и њихов ред.
- Реализација интерфејса
-
Обрада референци на објекте: Размотрите како ће се серијализовати објекти са циклуским референцама или дуплираним референцама на исти објекат. Може се користити механизам за чување ID-ева објеката.
-
Обрада верзија: Предвидите како ће се вршити десериализација података, серијализованих у старијој верзији протокола.
Пример основне реализације (без обраде сложених случајева):
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MySerializer {
// Записује целобројно поље
public void writeInt(OutputStream os, int value) throws IOException {
os.write((value >>> 24) & 0xFF);
os.write((value >>> 16) & 0xFF);
os.write((value >>> 8) & 0xFF);
os.write((value >>> 0) & 0xFF);
}
// Чита целобројно поље
public int readInt(InputStream is) throws IOException {
int value = 0;
value = (is.read() << 24);
value |= (is.read() << 16);
value |= (is.read() << 8);
value |= (is.read() << 0);
return value;
}
// Записује низ
public void writeString(OutputStream os, String value) throws IOException {
byte[] bytes = value.getBytes("UTF-8");
writeInt(os, bytes.length); // Записује дужину
os.write(bytes); // Записује бајтове
}
// Чита низ
public String readString(InputStream is) throws IOException {
int length = readInt(is); // Чита дужину
byte[] bytes = new byte[length];
is.read(bytes); // Чита бајтове
return new String(bytes, "UTF-8");
}
// Пример за серијализацију објекта Person
public void serialize(OutputStream os, Person person) throws IOException {
writeString(os, person.getName());
writeInt(os, person.getAge());
}
// Пример за десериализацију објекта Person
public Person deserialize(InputStream is) throws IOException {
String name = readString(is);
int age = readInt(is);
return new Person(name, age);
}
// Вспомагателни клас
public static class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public static void main(String[] args) throws IOException {
MySerializer serializer = new MySerializer();
Person originalPerson = new Person("Alice", 30);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serializer.serialize(baos, originalPerson);
byte[] serializedData = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
Person deserializedPerson = serializer.deserialize(bais);
System.out.println("Original: " + originalPerson.getName() + ", " + originalPerson.getAge());
System.out.println("Deserialized: " + deserializedPerson.getName() + ", " + deserializedPerson.getAge());
}
}
Креирање сопственог протокола захтева пажљиво планирање и узимање у обзир многих фактора као што су перформансе, компактност, верзионирање и обрада сложених структура података. Често се користе већ постојеће библиотеке (ProtoBuf, Kryo, Avro) уместо креирања протокола од нуле.