Cum să creezi propriul protocol de serializare?
sobes.tech AI
Răspuns de la AI
Pentru a crea propriul protocol de serializare în Java, trebuie să definești formatul datelor și să implementezi logica de citire/scriere.
-
Definește formatul datelor: Hotărăște cum vor fi reprezentate obiectele în formă de bytes. Poate fi un format binar (mai compact) sau text (mai ușor de citit). De exemplu, poți folosi un prefix de lungime înaintea câmpurilor.
-
Implementează citirea și scrierea:
- Creează o clasă
MySerializer(sau similar), care va conține metodeleserializeșideserialize. - Metoda
serializeva primi un obiect și unOutputStream, scriind bytes-urile obiectului conform formatului definit. - Metoda
deserializeva primi unInputStreamși va reconstrui obiectul din bytes.
- Creează o clasă
-
Marchează clasele pentru serializare:
- Clasele care trebuie serializate trebuie să aibă un mecanism de comunicare cu serializer-ul. Acest lucru poate fi:
- Implementarea interfeței
Serializable(dar folosește mecanismul standard Java) - Definirea unor metode personalizate
writeObjectșireadObject(cu semnături proprii) - Utilizarea de adnotări pentru a indica câmpurile care trebuie serializate și ordinea lor.
- Implementarea interfeței
- Clasele care trebuie serializate trebuie să aibă un mecanism de comunicare cu serializer-ul. Acest lucru poate fi:
-
Gestionarea referințelor la obiecte:
- Gândește-te cum vor fi serializate obiectele cu referințe ciclice sau duplicate. Poți folosi un mecanism de salvare a ID-urilor obiectelor.
-
Gestionarea versiunilor:
- Asigură-te că poți deserializa date serializate cu versiuni mai vechi ale protocolului.
Exemplu de implementare de bază (fără cazuri complexe):
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");
}
public void serialize(OutputStream os, Person person) throws IOException {
writeString(os, person.getName());
writeInt(os, person.getAge());
}
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());
}
}
Crearea propriului protocol necesită o planificare atentă și luarea în considerare a multor factori, precum performanța, compactitatea, gestionarea versiunilor și procesarea structurilor de date complexe. Deseori, se folosesc biblioteci existente (ProtoBuf, Kryo, Avro) în loc să se creeze un protocol de la zero.