Sobes.tech
Senior

როგორ შევქმნათ საკუთარი სერილიზაციის პროტოკოლი?

sobes.tech AI

პასუხი AI-სგან

Java-да өзіңдүн сериализация протоколун түзүү үчүн, маалымат форматын аныктоо жана окуу/жазуу логикасын ишке ашыруу керек.

  1. Маалымат форматын аныктоо: Объекттер байт форматына кандайча көрсөтүлөрүн чечиңиз. Бул бинардык формат (азыркы компакттуу) же тексттик (жөнөкөй окула турган) болушу мүмкүн. Мисалы, өрөөндөрдүн алдында узундук префиксин колдонсо болот.

  2. Окуу жана жазуу ишке ашыруу:

    • MySerializer сыяктуу класс түзүңүз, ал serialize жана deserialize методдорун камтыйт.
    • serialize методу объект жана OutputStream кабыл алып, объекттин байттарын белгиленген форматка ылайык жазат.
    • deserialize методу InputStream кабыл алып, байттардан объектти калыбына келтирет.
  3. Сериализация үчүн класстарды белгилөө: Синфтар, алар сериализациялануучу, сериализатор менен иштешүү механизми болушу керек. Бул:

    • Serializable интерфейсин ишке ашыруу (бирок анда Javaнын стандарттык механизми колдонулат).
    • Өзгөчө writeObject жана readObject методдорун аныктоо (стандарттык сериализациядагыдай, бирок өзүнүн сигнатурасы менен).
    • Поляларды сериализациялоо жана алардын тартибин белгилөө үчүн аннотацияларды колдонуу.
  4. Объекттерге шилтемелерди иштетүү: Циклдүү шилтемелер же бирдей объектке көп шилтемелер менен иштөө механизмин карап көрүңүз. Объекттердин IDлерин сактоо механизми колдонулушу мүмкүн.

  5. Версияларды иштетүү: Эскирген протокол версиясында сериализацияланган маалыматтарды десериализациялоо процесси кандай болорун алдын ала карап коюңуз.

Мисал үчүн негизги ишке ашыруу (кыйын учурларды эске албастан):

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) колдонулат, нөлдөн жаңы протокол түзүүдөн алыс.