JavaRush /Java Blog /Random-TK /Java-da serializasiýa we deserializasiýa

Java-da serializasiýa we deserializasiýa

Toparda çap edildi
Salam! Şu günki leksiýamyzda Java-da serializasiýa we deserializasiýa barada gürleşeris. Simpleönekeý mysaldan başlalyň. Kompýuter oýnunyň döredijisi diýeliň. 90-njy ýyllarda ulalan bolsaňyz we şol döwürdäki oýun konsollaryny ýada salsaňyz, şu gün olaryň aç-açan bir zadynyň ýokdugyny bilýärsiňiz - oýunlary tygşytlamak we ýüklemek :) Bolmasa ... göz öňüne getiriň! Bu gün beýle mümkinçilik bolmasa bir oýnuň şowsuzlyga uçramagyndan gorkýaryn! Aslynda, oýun “tygşytlamak” we “ýüklemek” näme? Adaty manyda, munuň nämedigine düşünýäris: oýny geçen gezek giden ýerimizden dowam etdirmek isleýäris. Munuň üçin oýny ýüklemek üçin ulanýan “gözegçilik nokady” döredýäris. Thisöne bu gündelik manyda däl-de, “programmist” manysynda nämäni aňladýar? Jogap ýönekeý: programmamyzyň ýagdaýyny halas edýäris. Ispaniýa üçin strategiýa oýun oýnaýarsyňyz diýeliň. Oýunyňyzyň ýagdaýy bar: haýsy sebitlere eýeçilik edýär, kimiň baýlygy bar, kim bilen ýaranlyk edýär we tersine, kim söweşýär we ş.m. Maglumatlary soň dikeltmek we oýny dowam etdirmek üçin bu maglumatlar, programmamyzyň ýagdaýy, nähilidir bir ýagdaýda saklanmalydyr. Serializasiýa we deserializasiýa mehanizmleri hut şu ulanylýar . Serializasiýa - obýektiň ýagdaýyny baýt yzygiderliliginde saklamak prosesi. Deserializasiýa - bu baýtlardan bir obýekti täzeden gurmak prosesi. Islendik Java obýekti baýtlaryň yzygiderliligine öwrülýär. Bu näme üçin? Programmalaryň özbaşdak ýokdugyny birnäçe gezek aýtdyk. Köplenç biri-biri bilen täsirleşýärler, maglumat alyşýarlar we ş.m. Munuň üçin baýt formaty amatly we täsirli. Mysal üçin, synp obýektimizi SavedGame(saklanan oýun) baýtlaryň yzygiderliligine öwrüp bileris, şol baýtlary tordan başga bir kompýutere geçirip bileris, ikinji kompýuterde bolsa şol baýtlary Java obýektine öwrüp bileris! Eşitmek kyn, şeýlemi? Megerem, bu prosesi guramak aňsat bolmaz: / Bagtymyza, ýok! :) Java-da Serializable interfeýsi seriallaşdyrma amallary üçin jogapkärdir . Bu interfeýs gaty ýönekeý: ony ulanmak üçin ýekeje usul hem ulanmagyň zerurlygy ýok! Tygşytly oýun synpymyz şeýle bolar:
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) +
               '}';
   }
}
Üç maglumat toplumy sebitler, ykdysadyýet we diplomatiýa barada maglumat üçin jogapkärdir we Serializable interfeýsi Java enjamyna: " Hemme zat gowy, bir zat bar bolsa, bu synpyň obýektleri seriallaşdyrylyp bilner " -diýdi. Hiç hili usuly bolmadyk interfeýs geň görünýär: / Näme üçin zerur? Bu soraga jogap ýokarda: diňe Java enjamyna zerur maglumatlary bermek. Öňki leksiýalaryň birinde marker interfeýslerini gysgaça aýdypdyk. Bular geljekde Java maşynyna peýdaly boljak goşmaça maglumatlar bilen synplarymyzy bellän ýörite maglumat interfeýsleridir. Olarda durmuşa geçirilmeli usullar ýok. Şeýlelikde, Serializable şeýle interfeýsleriň biridir. Anotherene bir möhüm nokat: private static final long serialVersionUIDsynpda kesgitlän üýtgeýjimiz. Näme üçin zerur? Bu meýdan seriallaşdyrylan synpyň özboluşly wersiýa kesgitleýjisini öz içine alýar . Serializable interfeýsini amala aşyrýan islendik synpyň wersiýa kesgitleýjisi bar. Synpyň mazmuny - meýdanlar, beýannama tertibi, usullary esasynda hasaplanýar. Meýdanyň görnüşini we / ýa-da synpymyzdaky meýdanlaryň sanyny üýtgetsek, wersiýa kesgitleýjisi derrew üýtgär. serialVersionUID synp seriallaşdyrylanda hem ýazylýar. Deserializasiýa etmäge synanyşanymyzda, ýagny bir obýekti baýtlar toplumyndan dikeltjek bolanymyzda, baha programmamyzdaky synpyň serialVersionUIDbahasy bilen deňeşdirilýär . serialVersionUIDGymmatlyklar gabat gelmese, java.io.InvalidClassException zyňylar. Munuň mysalyny aşakda göreris. Şeýle ýagdaýlardan gaça durmak üçin bu wersiýa ID-ni synpymyz üçin el bilen düzýäris. Biziň ýagdaýymyzda, diňe 1-e deň bolar (islän başga belgiňizi çalşyp bilersiňiz). Bolýar, obýektimizi seriallaşdyryp SavedGame, nämeleriň bolýandygyny görmegiň wagty geldi!
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();
   }
}
Görşüňiz ýaly, 2 sapak döretdik - FileOutputStreamwe ObjectOutputStream. Olaryň birinjisi maglumatlary faýla ýazyp biler, ikinjisi obýektleri baýtlara öwrüp biler. Siz eýýäm şuňa meňzeş “höwürtgelenen” gurluşyklary gördüňiz, mysal üçin, new BufferedReader(new InputStreamReader(...))öňki leksiýalarda, sizi gorkuzmaly däldirler :) Iki sapakdan ybarat “zynjyr” döredip, iki işi ýerine ýetirýäris: obýekti SavedGamebaýtlar toplumyna öwürýäris; usuly bilen faýla ýazdyryň writeObject(). Theogsa-da, alan zatlarymyzy hatda barlamadyk! Faýla seretmegiň wagty geldi! * Bellik: faýly öňünden döretmek zerurlygy ýok. Şol at bilen bir faýl ýok bolsa, awtomatiki usulda dörediler * Ine, mazmuny! Saved SavedGame [diplomatiýaInfot [Ljava / lang / String; [resourcesInfoq ~ [territoriýaInfoq ~ xpur] РЅРёСЏ Р · Р ° РСЏР »Р ° РїР · РёС † РёСЋ нейтрР° Р» итетР° uq ~ t "РЈ РЃСЃРїР ° РЅРёРё 100 Р · РѕР» РССРР РѕСЃСЃРёРё 80 Р · РѕР »РССРР РЅС † РёРё 90 Р · РѕР» РССРР uq & t & Р˜СЃРїР ° РЅРёРё 6 РїРЂРѕР %Р С. † РёР№t & РЈ ФрР° РЅС † РеРё 8 РїСЂРѕРІРІРёРЅС † РёР№ Oops :( Programmamyz işlemedik ýaly :( Aslynda, işledi. Faýlyňyza bir topar baýt geçirendigimizi ýadyňyzda saklaýarsyňyz. Diňe bir obýekt ýa-da tekst däl? Bu toplumyň görnüşi şeýle :) Bu halas edilen oýunymyz! Asyl obýektimizi dikeltmek, ýagny oýny giden ýerimizden ýüklemek we dowam etdirmek islesek, bize gerek ters proses, deserializasiýa ... Bu biziň ýagdaýymyzda şeýle bolar:
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);
   }
}
Ine, netije! SavedGame {territoriýaInfo = [Ispaniýanyň 6 welaýaty, Russiýanyň 10 welaýaty, Fransiýanyň 8 welaýaty bar], resursInfo = [Ispaniýanyň 100 altyn, Russiýanyň 80 altyn, Fransiýanyň 90 altyn], diplomatiýaInfo = [Fransiýa Russiýa bilen söweşýär, Ispaniýa bitaraplyk pozisiýasyny eýeledi]} Ajaýyp! Ilki bilen oýnumyzyň ýagdaýyny bir faýla ýazdyryp, soň bolsa faýldan dikeltmegi başardyk. Indi edil şonuň ýaly etmäge synanyşalyň, ýöne SavedGamewersiýa kesgitleýjisini synpymyzdan aýyralyň. Iki synpymyzy täzeden ýazmarys, içindäki kod birmeňzeş bolar, diňe SavedGameaýyrarys private static final long serialVersionUID. Ynha, seriallaşdyrylandan soň obýektimiz: ¬n sr SavedGameі € MіuOm ‰ [diplomatiýaInfot [Ljava / lang / String; [resourcesInfoq ~ [territoriýalarInfoq ~ xpur ‚СЃ Р РСсией, Р˜СЃРїР ° РЅРЏР · Р ° РЅСЏР» Р ° РїРѕР · РёС † РёСЋ нейтрР° Р »РёС‚етР° uq ~ t" РЈ Р˜С · РѕР »РѕС‚Р ° t РЈСЃСЃРёРё 80 Р · РѕР» отР° t! РЈ РЂСЂР ° РЅС † РёРё 90 Р · РѕР »РССРР їСЂРѕРІРёРЅС † РёР№t% РЈ Р РСЃСЃРёРё 10 РїСЂРѕРІРЅРёРЅС † РёР№t & РЈ РЂСЂР ° РЅС † РёРё 8 РїСЂРѕРІРІРёРЅС † РёР atible: stream classdesc serialVersionUID = - 196410440475012755, ýerli synp serialVersionUID = -6675950253085108747 Bu ýokarda agzalan şol bir kadadan çykma. Bu hakda has köp talyplarymyzyň biriniň makalasynda okap bilersiňiz. Theeri gelende aýtsak, bir möhüm nokady sypdyrdyk. aňsatlyk bilen seriallaşdyrylýar: “Java” -yň elbetde käbirleri bar, munuň üçin içerki mehanizmler bar. Ouröne biziň serializablesynpymyzda ilkinjiler hökmünde däl-de, beýleki zatlara salgylanmalar ýaly meýdanlar bar bolsa näme etmeli? Mysal üçin , synpymyz bilen işlemek TerritoriesInfoüçin aýratyn synplary döredeliň . 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 + '\'' +
               '}';
   }
}
Nowöne indi bir soragymyz bar: üýtgedilen synpy seriallaşdyrmak islesek, bu synplaryň hemmesi Serializable bolmalymy 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 +
               '}';
   }
}
Geliň, muny iş ýüzünde barlap göreliň! Geliň, hemme zady häzirkisi ýaly goýalyň we obýekti seriallaşdyrmaga synanyşalyň 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();
   }
}
Netije: "esasy" java.io.NotSerializableException: DiplomatiýaInfo şowsuz! Aslynda, bu biziň soragymyza jogap. Bir obýekti seriýalasaňyz, mysal üýtgeýjilerinde görkezilen ähli obýektler seriýalaşdyrylýar. Şol obýektler üçünji obýektlere-de salgylanýan bolsa, olar hem seriýalaşdyrylýar. Mahabat infinitumda we ş.m. Bu zynjyryň ähli synplary Serializable bolmaly, ýogsam olar seriallaşdyrylmaz we kadadan çykma bolar. Theeri gelende aýtsak, bu geljekde kynçylyk döredip biler. Mysal üçin, seriallaşdyrma wagtynda synpyň bir bölegi gerek bolmasa, näme etmeli? Ora-da mysal üçin, TerritoryInfokäbir kitaphananyň bir bölegi hökmünde programmamyzda bir synp miras aldyk. Şeýle-de bolsa, Serializable däl we şoňa görä üýtgedip bilmeris. Görnüşi ýaly, TerritoryInfosynpymyza bir meýdan goşup SavedGamebilmeris , sebäbi şonda tutuş synp SavedGameseriallaşdyrylmaz! Mesele: / Java-da serializasiýa we deserializasiýa - 2Bu görnüşdäki meseleler açar söz ulanyp Java-da çözülýär transient. Bu açar sözi synp meýdanyna goşsaňyz, bu meýdanyň bahasy seriýalanmaz. Geliň, synpymyzyň meýdanlaryndan birini ýasamaga synanyşalyň SavedGame transient, şondan soň bir obýekti seriallaşdyrarys we dikelderis.
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();


   }
}
Ine, netije: SavedGame {territoriýalarInfo = null, resourcesInfo = ResursInfo {info = 'Ispaniýada 100 altyn, Russiýada 80 altyn, Fransiýada 90 altyn'}, diplomatiýaInfo = DiplomacyInfo {info = 'Fransiýa Russiýa bilen söweşýär, Ispaniýa bitaraplyk pozisiýasyny eýeledi '}}transient Şol bir wagtyň özünde, meýdança haýsy bahanyň beriljekdigi baradaky soraga jogap aldyk . Bellenen baha berilýär. Obýektler meselesinde null. Boş wagtyňyz seriýalaşdyrmak baradaky bu ajaýyp makalany okap bilersiňiz . ExternalizableŞeýle hem , indiki leksiýada gürleşjek interfeýs hakda gürrüň edýär . Mundan başga-da, “Head-First Java” kitabynda bu mowzuk hakda bir bölüm bar, oňa üns beriň :)
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION