Kuidas luua oma serialiseerimisprotokoll?
sobes.tech AI
Vastus AI-lt
Selleks, et luua oma serialiseerimisprotokoll Java's, tuleb määratleda andmevorming ja rakendada lugemise/kirjutamise loogika.
-
Määratle andmevorming: Otsusta, kuidas objektid esitatakse baitvormingus. See võib olla binaarne formaat (kompaktsisem) või tekstiline (kergem lugeda). Näiteks võib kasutada pikkuse eellühendit enne välju.
-
Rakenda lugemine ja kirjutamine:
- Loo klass
MySerializer(või sarnane), mis sisaldab meetodeidserializejadeserialize. - Meetod
serializevõtab objekti jaOutputStream, kirjutades objekti baitide voogu vastavalt määratletud formaadile. - Meetod
deserializevõtabInputStreamja taastab objekti baitidest.
- Loo klass
-
Klasse märgistamine serialiseerimiseks: Klassid, mida tuleb serialiseerida, peavad omama mehhanismi koostööks serialiseerijaga. See võib olla:
Serializableliidese rakendamine (aga siis kasutatakse Java standardmehhanismi).- Kasutaja määratletud meetodid
writeObjectjareadObject(sarnaseltreadObjectjawriteObjectstandardserialiseerimisel, kuid oma signatuuriga). - Anotatsioonide kasutamine, et märkida serialiseeritavad väljad ja nende järjekord.
-
Viidete töötlemine: Mõtle, kuidas serialiseeritakse objektid tsükliliste viidete või duplitseerivate viidete korral samale objektile. Võib kasutada objekti ID-de mehhanismi.
-
Versioonide töötlemine: Planeeri, kuidas toimub vanemate versioonide andmete deserialiseerimine.
Näide põhitasemel (ilma keerukate juhtumite käsitlemiseta):
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class MySerializer {
// Kirjutab täisarvu välja
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);
}
// Loeb täisarvu välja
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;
}
// Kirjutab stringi välja (lihtne viis: pikkus + stringi baitid)
public void writeString(OutputStream os, String value) throws IOException {
byte[] bytes = value.getBytes("UTF-8");
writeInt(os, bytes.length); // Kirjutab stringi pikkuse
os.write(bytes); // Kirjutab baitid
}
// Loeb stringi välja
public String readString(InputStream is) throws IOException {
int length = readInt(is); // Loeb stringi pikkuse
byte[] bytes = new byte[length];
is.read(bytes); // Loeb baitid
return new String(bytes, "UTF-8");
}
// Näide lihtsa objekti Person serialiseerimisest
public void serialize(OutputStream os, Person person) throws IOException {
writeString(os, person.getName());
writeInt(os, person.getAge());
}
// Näide lihtsa objekti Person deserialiseerimisest
public Person deserialize(InputStream is) throws IOException {
String name = readString(is);
int age = readInt(is);
return new Person(name, age);
}
// Abi klass näidisklass
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("Originaal: " + originalPerson.getName() + ", " + originalPerson.getAge());
System.out.println("Deserialiseeritud: " + deserializedPerson.getName() + ", " + deserializedPerson.getAge());
}
}
Selleks, et luua oma protokoll, nõuab hoolikat planeerimist ja paljusid tegureid, nagu jõudlus, kompaktsus, versioonimine ja keerukate andmestruktuuride töötlemine. Sageli kasutatakse juba olemasolevaid teeke (ProtoBuf, Kryo, Avro) selle asemel, et protokolli nullist luua.