Sobes.tech
Senior

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.

  1. 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.

  2. Rakenda lugemine ja kirjutamine:

    • Loo klass MySerializer (või sarnane), mis sisaldab meetodeid serialize ja deserialize.
    • Meetod serialize võtab objekti ja OutputStream, kirjutades objekti baitide voogu vastavalt määratletud formaadile.
    • Meetod deserialize võtab InputStream ja taastab objekti baitidest.
  3. Klasse märgistamine serialiseerimiseks: Klassid, mida tuleb serialiseerida, peavad omama mehhanismi koostööks serialiseerijaga. See võib olla:

    • Serializable liidese rakendamine (aga siis kasutatakse Java standardmehhanismi).
    • Kasutaja määratletud meetodid writeObject ja readObject (sarnaselt readObject ja writeObject standardserialiseerimisel, kuid oma signatuuriga).
    • Anotatsioonide kasutamine, et märkida serialiseeritavad väljad ja nende järjekord.
  4. 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.

  5. 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.