JavaRush /Блоги Java /Random-TG /Сериализатсия ва бесериализатсия дар Java

Сериализатсия ва бесериализатсия дар Java

Дар гурӯҳ нашр шудааст
Салом! Дар лексияи имрӯза мо дар бораи сериализатсия ва сериализатсия дар Java сӯҳбат хоҳем кард. Биёед бо як мисоли оддӣ оғоз кунем. Фарз мекунем, ки шумо офаринандаи бозии компютерӣ ҳастед. Агар шумо дар солҳои 90-ум ба воя расидаед ва консолҳои бозии он замонҳоро дар хотир доред, шумо эҳтимол медонед, ки онҳо имрӯз як чизи аён надоштанд - бозиҳои захиракунӣ ва боркунӣ :) Агар не... тасаввур кунед! Метарсам, ки имруз бозие, ки чунин имкон надорад, ба нокомй дучор мешавад! Ва, воқеан, бозӣ "сарфа кардан" ва "бор кардан" чист? Хуб, ба маънои муқаррарӣ, мо мефаҳмем, ки ин чӣ аст: мо мехоҳем бозиро аз ҳамон ҷое, ки дафъаи гузашта монда будем, идома диҳем. Барои ин, мо як навъ "нуқтаи назорат" -ро эҷод мекунем, ки мо онро барои бор кардани бозӣ истифода мебарем. Аммо ин на ба маънои ҳаррӯза, балки ба маънои «барномасоз» чӣ маъно дорад? Ҷавоб оддӣ аст: мо ҳолати барномаи худро нигоҳ дорем. Фарз мекунем, ки шумо барои Испания як бозии стратегӣ бозӣ мекунед. Бозии шумо давлат дорад: кӣ соҳиби кадом қаламрав аст, кӣ чӣ қадар захира дорад, кӣ бо кӣ иттифоқ дорад ва кӣ, баръакс, дар ҷанг аст ва ғайра. Ин маълумот, ҳолати барномаи мо, бояд ба гунае нигоҳ дошта шавад, то баъдтар маълумот барқарор карда шавад ва бозӣ идома ёбад. Маҳз барои ҳамин механизмҳои сериализатсия ва сериализатсия истифода мешаванд . Сериализатсия раванди нигоҳ доштани ҳолати an object ба пайдарпайии byteҳо мебошад. Десериализатсия раванди аз нав сохтани an object аз ин byteҳо мебошад. Ҳар як an objectи Java ба пайдарпайии byteҳо табдил дода мешавад. Он барои чӣ? Мо на як бору ду бор гуфта будем, ки барномахо худ аз худ вучуд надоранд. Аксар вақт онҳо бо ҳамдигар ҳамкорӣ мекунанд, маълумот мубодила мекунанд ва ғайра. Ва формати byte барои ин қулай ва муассир аст. Мо метавонем, масалан, an objectи синфии худро SavedGame(бозии захирашуда) ба пайдарпайии byteҳо табдил диҳем, он byteҳоро тавассути шабака ба компютери дигар интиқол диҳем ва дар компютери дуюм он byteҳоро ба an objectи Java табдил диҳем! Гӯш кардан душвор аст, дуруст? Аз афташ, ташкor ин процесс осон нахохад буд:/ Хушбахтона, не! :) Дар Java, интерфейси Serializable барои равандҳои сериализатсия масъул аст . Ин интерфейс бениҳоят содда аст: барои истифодаи он ба шумо як усули ягона лозим нест! Ин аст, ки синфи бозии наҷоти мо чунин хоҳад буд:
import java.io.Serializable;
import java.util.Arrays;

public class SavedGame implements Serializable {

   private static final long serialVersionUID = 1L;

   private String[] territoriesInfo;
   private String[] resourcesInfo;
   private String[] diplomacyInfo;

   public SavedGame(String[] territoriesInfo, String[] resourcesInfo, String[] diplomacyInfo){
       this.territoriesInfo = territoriesInfo;
       this.resourcesInfo = resourcesInfo;
       this.diplomacyInfo = diplomacyInfo;
   }

   public String[] getTerritoriesInfo() {
       return territoriesInfo;
   }

   public void setTerritoriesInfo(String[] territoriesInfo) {
       this.territoriesInfo = territoriesInfo;
   }

   public String[] getResourcesInfo() {
       return resourcesInfo;
   }

   public void setResourcesInfo(String[] resourcesInfo) {
       this.resourcesInfo = resourcesInfo;
   }

   public String[] getDiplomacyInfo() {
       return diplomacyInfo;
   }

   public void setDiplomacyInfo(String[] diplomacyInfo) {
       this.diplomacyInfo = diplomacyInfo;
   }

   @Override
   public String toString() {
       return "SavedGame{" +
               "territoriesInfo=" + Arrays.toString(territoriesInfo) +
               ", resourcesInfo=" + Arrays.toString(resourcesInfo) +
               ", diplomacyInfo=" + Arrays.toString(diplomacyInfo) +
               '}';
   }
}
Се маҷмӯи додаҳо барои маълумот дар бораи ҳудудҳо, иқтисод ва дипломатия масъуланд ва интерфейси Serializable ба мошини Java мегӯяд: " Ҳама чиз хуб аст, агар чизе бошад, an objectҳои ин синфро метавон силсилавӣ кард ." Интерфейс, ки ягон усул надорад, аҷиб менамояд :/ Чаро он лозим аст? Ҷавоб ба ин савол дар боло аст: танҳо барои додани маълумоти зарурӣ ба мошини Java. Дар яке аз лексияҳои қаблӣ мо интерфейсҳои маркерро мухтасар зикр кардем. Инҳо интерфейсҳои махсуси иттилоотӣ мебошанд, ки танҳо дарсҳои моро бо маълумоти иловагӣ қайд мекунанд, ки барои мошини Java дар оянда муфид хоҳанд буд. Онҳо ягон усуле надоранд, ки бояд амалӣ шаванд. Ҳамин тавр, Serializable яке аз чунин интерфейсҳост. Боз як нуктаи муҳим: тағирёбандае, private static final long serialVersionUIDки мо дар синф муайян кардем. Чаро он лозим аст? Ин майдон дорои идентификатори ягонаи versionи синфи сериализатсияшуда мебошад . Ҳар синфе, ки интерфейси Serializable-ро амалӣ мекунад, идентификатори version дорад. Он дар асоси мундариҷаи синф - майдонҳо, тартиби эъломия, усулҳо ҳисоб карда мешавад. Ва агар мо навъи майдон ва/ё шумораи майдонҳоро дар синфи худ тағир диҳем, идентификатори version фавран тағир меёбад. serialVersionUID инчунин вақте навишта мешавад, ки синф сериализатсия карда мешавад. Вақте ки мо кӯшиш мекунем, ки сериализатсия кунем, яъне an objectро аз маҷмӯи byteҳо барқарор кунем, арзиш serialVersionUIDбо арзиши serialVersionUIDсинф дар барномаи мо муқоиса карда мешавад. Агар арзишҳо мувофиқат накунанд, java.io.InvalidClassException партофта мешавад. Мо дар зер мисоли инро мебинем. Барои роҳ надодан ба чунин ҳолатҳо, мо танҳо ин ID versionро барои синфи худ дастӣ муқаррар мекунем. Дар ҳолати мо, он танҳо ба 1 баробар хоҳад буд (шумо метавонед рақами дигареро, ки ба шумо маъқул аст, иваз кунед). Хуб, вақти он расидааст, ки an objectи худро сериализатсия кунем SavedGameва бубинем, ки чӣ мешавад!
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Main {

   public static void main(String[] args) throws IOException {

       // create our object
       String[] territoryInfo = {"Spain has 6 provinces", "Russia has 10 provinces", "France has 8 provinces"};
       String[] resourcesInfo = {"Spain has 100 gold", "Russia has 80 gold", "France has 90 gold"};
       String[] diplomacyInfo = {"France is at war with Russia, Spain has taken a position of neutrality"};

       SavedGame savedGame = new SavedGame(territoryInfo, resourcesInfo, diplomacyInfo);

       //create 2 threads to serialize the object and save it to a file
       FileOutputStream outputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);

       // save game to file
       objectOutputStream.writeObject(savedGame);

       // close the stream and release resources
       objectOutputStream.close();
   }
}
Тавре ки шумо мебинед, мо 2 ришта эҷод кардем - FileOutputStreamва ObjectOutputStream. Якуми онҳо метавонад ба файл маълумот нависад ва дуюм метавонад an objectҳоро ба byte табдил диҳад. Шумо аллакай чунин конструкцияҳои «лона»-ро дидаед, масалан, new BufferedReader(new InputStreamReader(...))дар лексияҳои қаблӣ, пас онҳо набояд шуморо тарсонанд :) Бо сохтани чунин «занҷир»-и ду ришта, мо ҳарду вазифаро иҷро мекунем: an objectро SavedGameба маҷмӯи byteҳо табдил медиҳем. ва онро ба файл бо истифода аз усули захира кунед writeObject(). Ва, дар омади гап, мо ҳатто тафтиш накардаем, ки чӣ дорем! Вақти он расидааст, ки файлро бубинем! *Эзоҳ: файлро пешакӣ сохтан лозим нест. Агар файле бо ин ном вуҷуд надошта бошад, он ба таври худкор эҷод карда мешавад* Ва ин аст мундариҷаи он! ¬н sr SavedGame [ diplomatacyInfot [Ljava/lang/String;[ resourcesInfoq ~ [ territoriesInfoq ~ xpur [Ljava.lang.String;ТVзй{G xp t pФранцвоюРμС РЅС†РІРѕСЋРμС РЃСЃСРµРЃСЃС ° РЅРёСЏ Р·Р°Ряла позицию нейтралитетаuq ~ t "РЈ Р˜СЃРїР°РЅРёР°Р°Р0РёРёР00» РѕСЃСЃРёРё 80 золотаt !РЈ Франции 90 золотаuq ~ t &РЈ Р˜СЃРїР°РЅР˜СЃРїР°РЅРˠспанІиР% ІииР6 Ј Р РѕСЃСЃРёРё 10 РїСЂРѕРІРёРЅС †РёР№t &РЈ ФранцРеРё 8 проввинций Оп :( Чунин ба назар мерасад, ки барномаи мо кор накард :( Дар асл, он кор кард. Шумо дар хотир доред, ки мо айнан як маҷмӯи byteҳоро ба файл интиқол додем, ва на танҳо an object ё матн?Хуб, ин маҷмӯа чунин аст :) Ин бозии захирашудаи мост! раванди баръакс, десериализатсия ... Ин дар ҳолати мо чунин хоҳад буд:
import java.io.*;

public class Main {

   public static void main(String[] args) throws IOException, ClassNotFoundException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

       SavedGame savedGame = (SavedGame) objectInputStream.readObject();

       System.out.println(savedGame);
   }
}
Ва ин аст натиҷа! SavedGame{territoriesInfo=[Испания 6 вилоят дорад, Русия 10 вилоят дорад, Фаронса 8 вилоят дорад], resourcesInfo=[Испания 100 тилло, Русия 80 тилло, Фаронса 90 тилло дорад], diplomatacyInfo=[Фаронса бо Русия ҷанг мекунад, Испания мавкеи бетарафиро ишгол кардааст]} Бузург! Мо тавонистем аввал ҳолати бозии худро дар файл захира кунем ва сипас онро аз файл барқарор кунем. Акнун биёед кӯшиш кунем, ки ҳамин тавр кунем, аммо SavedGameидентификатори versionро аз синфи мо хориҷ кунед. Мо ҳардуи синфҳои худро аз нав наменависем, рамзи онҳо якхела хоҳад буд, мо танҳо SavedGameнест мекунем private static final long serialVersionUID. Ин аст an objectи мо пас аз сериализатсия: ¬н sr SavedGameі€MіuОm‰ [ diplomatacyInfot [Ljava/lang/String;[ resourcesInfoq ~ [ territoriesInfoq ~ xpur [Ljava.lang.String;ТВзй{G xp t pФраняраиѽц ‚ СЃ РРоссией, Р˜СЃРїР°РЅРЏР·Р°РЅСЏР»Р° RїРѕР·РёС†РёСЋ нейтралитралитралитРˈР ~атР˅Т. ёРё 100 Р · олотаt РЈ Р РѕСЃСЃРёРё 80 золотаt !РЈ Франции 90 золотаuq ~ t &СЃРёР˅ t &СЃёР˅ їСЂРѕРІРёРЅС† РёР№t %РЈ Р РѕСЃСЃРёРё 10 провнинцийt &РЈ Франции ба 8 РРРёРЅС кӯшиш кардан ба And†РёРЅС онро сериал кунед, ин ҳодиса рӯй дод: InvalidClassException: синфи маҳаллӣ номувофиқ: stream classdesc serialVersionUID = - 196410440475012755, local class serialVersionUID = -6675950253085108747 Ин ҳамон истисноест, ки дар боло зикр шуд.Дар ин бора метавонед дар мақолаи яке аз донишҷӯёни мо бихонед.Дар омади гап, як нуктаи муҳимро аз даст додем.Маълум аст, ки сатрҳо ва примитивҳо ба осонӣ сериализатсия карда мешаванд: Java бешубҳа баъзеҳо дорад- пас барои ин механизмҳои дарунсохт мавҷуданд. Аммо агар serializable-синфи мо майдонҳое дошта бошад, ки на ҳамчун ибтидоӣ, балки ҳамчун истинод ба an objectҳои дигар ифода карда шаванд? Биёед, масалан , TerritoriesInfoбарои кор бо синфи худ синфҳои алоҳида эҷод кунем . ResourcesInfoDiplomacyInfoSavedGame
public class TerritoriesInfo {

   private String info;

   public TerritoriesInfo(String info) {
       this.info = info;
   }

   public String getInfo() {
       return info;
   }

   public void setInfo(String info) {
       this.info = info;
   }

   @Override
   public String toString() {
       return "TerritoriesInfo{" +
               "info='" + info + '\'' +
               '}';
   }
}

public class ResourcesInfo {

   private String info;

   public ResourcesInfo(String info) {
       this.info = info;
   }

   public String getInfo() {
       return info;
   }

   public void setInfo(String info) {
       this.info = info;
   }

   @Override
   public String toString() {
       return "ResourcesInfo{" +
               "info='" + info + '\'' +
               '}';
   }
}

public class DiplomacyInfo {

   private String info;

   public DiplomacyInfo(String info) {
       this.info = info;
   }

   public String getInfo() {
       return info;
   }

   public void setInfo(String info) {
       this.info = info;
   }

   @Override
   public String toString() {
       return "DiplomacyInfo{" +
               "info='" + info + '\'' +
               '}';
   }
}
Аммо ҳоло мо саволе дорем: оё ҳамаи ин синфҳо Serializable бошанд, агар мо мехоҳем синфи тағирёфтаро силсилаи кунем SavedGame?
import java.io.Serializable;
import java.util.Arrays;

public class SavedGame implements Serializable {

   private TerritoriesInfo territoriesInfo;
   private ResourcesInfo resourcesInfo;
   private DiplomacyInfo diplomacyInfo;

   public SavedGame(TerritoriesInfo territoriesInfo, ResourcesInfo resourcesInfo, DiplomacyInfo diplomacyInfo) {
       this.territoriesInfo = territoriesInfo;
       this.resourcesInfo = resourcesInfo;
       this.diplomacyInfo = diplomacyInfo;
   }

   public TerritoriesInfo getTerritoriesInfo() {
       return territoriesInfo;
   }

   public void setTerritoriesInfo(TerritoriesInfo territoriesInfo) {
       this.territoriesInfo = territoriesInfo;
   }

   public ResourcesInfo getResourcesInfo() {
       return resourcesInfo;
   }

   public void setResourcesInfo(ResourcesInfo resourcesInfo) {
       this.resourcesInfo = resourcesInfo;
   }

   public DiplomacyInfo getDiplomacyInfo() {
       return diplomacyInfo;
   }

   public void setDiplomacyInfo(DiplomacyInfo diplomacyInfo) {
       this.diplomacyInfo = diplomacyInfo;
   }

   @Override
   public String toString() {
       return "SavedGame{" +
               "territoriesInfo=" + territoriesInfo +
               ", resourcesInfo=" + resourcesInfo +
               ", diplomacyInfo=" + diplomacyInfo +
               '}';
   }
}
Хуб, биёед инро дар амал тафтиш кунем! Биёед ҳама чизро ҳамон тавре ки ҳоло ҳаст, тарк кунем ва кӯшиш кунем, ки an objectро силсилавӣ кунем SavedGame:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Main {

   public static void main(String[] args) throws IOException {

       // create our object
       TerritoriesInfo territoriesInfo = new TerritoriesInfo("Spain has 6 provinces, Russia has 10 provinces, France has 8 provinces");
       ResourcesInfo resourcesInfo = new ResourcesInfo("Spain has 100 gold, Russia has 80 gold, France has 90 gold");
       DiplomacyInfo diplomacyInfo =  new DiplomacyInfo("France is at war with Russia, Spain has taken a position of neutrality");


       SavedGame savedGame = new SavedGame(territoriesInfo, resourcesInfo, diplomacyInfo);

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

       objectOutputStream.writeObject(savedGame);

       objectOutputStream.close();
   }
}
Натиҷа: Истисно дар риштаи "main" java.io.NotSerializableException: DiplomacyInfo ноком шуд! Воқеан, дар ин ҷо ҷавоб ба саволи мост. Вақте ки шумо an objectро силсилавӣ мекунед, ҳама an objectҳое, ки он дар тағирёбандаҳои мисоли худ истинод мекунад, силсилавӣ карда мешаванд. Ва агар он an objectҳо инчунин ба an objectҳои сеюм муроҷиат кунанд, онҳо инчунин силсила карда мешаванд. Ва ғайра ва ғайра. Ҳама синфҳо дар ин занҷир бояд Serializable бошанд, вагарна онҳо сериализатсия намешаванд ва истисно партофта мешавад. Дар омади гап, ин метавонад дар оянда мушкилот эҷод кунад. Масалан, агар мо ҳангоми сериализатсия ба як қисми синф ниёз надорем, мо бояд чӣ кор кунем? Ё, масалан, TerritoryInfoмо як синфро дар барномаи худ ҳамчун як қисми китобхона мерос гирифтем. Аммо, он Serializable нест ва мувофиқан мо онро тағир дода наметавонем. Маълум мешавад, ки мо наметавонем майдонро TerritoryInfoба синфи худ илова кунем, зеро он гоҳ тамоми синф ғайридавлатӣ хоҳад шуд! Мушкилот:/ Мушкилоти ин гуна дар Java бо истифода аз калимаи калидӣ ҳал карда мешаванд . Агар шумо ин калимаи калидиро ба майдони синф илова кунед, арзиши ин майдон силсила карда намешавад. Биёед кӯшиш кунем, ки яке аз майдонҳои синфи худро созем , ки пас аз он мо як an objectро силсилавӣ ва барқарор мекунем. SavedGameSavedGameСериализатсия ва бесериализатсия дар Java - 2transientSavedGame transient
import java.io.Serializable;

public class SavedGame implements Serializable {

   private transient TerritoriesInfo territoriesInfo;
   private ResourcesInfo resourcesInfo;
   private DiplomacyInfo diplomacyInfo;

   public SavedGame(TerritoriesInfo territoriesInfo, ResourcesInfo resourcesInfo, DiplomacyInfo diplomacyInfo) {
       this.territoriesInfo = territoriesInfo;
       this.resourcesInfo = resourcesInfo;
       this.diplomacyInfo = diplomacyInfo;
   }

   //...getters, setters, toString()...
}



import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Main {

   public static void main(String[] args) throws IOException {

       // create our object
       TerritoriesInfo territoriesInfo = new TerritoriesInfo("Spain has 6 provinces, Russia has 10 provinces, France has 8 provinces");
       ResourcesInfo resourcesInfo = new ResourcesInfo("Spain has 100 gold, Russia has 80 gold, France has 90 gold");
       DiplomacyInfo diplomacyInfo =  new DiplomacyInfo("France is at war with Russia, Spain has taken a position of neutrality");


       SavedGame savedGame = new SavedGame(territoriesInfo, resourcesInfo, diplomacyInfo);

       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

       objectOutputStream.writeObject(savedGame);

       objectOutputStream.close();
   }
}


import java.io.*;

public class Main {

   public static void main(String[] args) throws IOException, ClassNotFoundException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
       ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

       SavedGame savedGame = (SavedGame) objectInputStream.readObject();

       System.out.println(savedGame);

       objectInputStream.close();


   }
}
Ва ин аст натиҷа: SavedGame{territoriesInfo=null, resourcesInfo=ResourcesInfo{info='Испания 100 тилло, Русия 80 тилло, Фаронса 90 тилло дорад'}, diplomatacyInfo=DiplomacyInfo{info='Фаронса бо Русия ҷанг мекунад, Испания мавкеи бетарафиро ишгол кард'}}transient Дар баробари ин мо ба саволе, ки ба -майдон чй арзиш дода мешавад, чавоб гирифтем . Он арзиши пешфарз таъин карда мешавад. Дар мавриди an objectҳо ин аст null. Дар вақти истироҳат шумо метавонед ин мақолаи олиро дар бораи сериализатсия хонед . Он инчунин дар бораи интерфейс Externalizable, ки мо дар лексияи оянда сӯҳбат хоҳем кард. Илова бар ин, дар китоби «Сар-аввал Java» боби ин мавзӯъ мавҷуд аст, ба он диққат диҳед :)
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION