Бул макалада биз сериалдаштыруу деген эмне экенин жана ал Javaда кантип иштээрин түшүндүрөбүз.
Сүрөт 1. Жиптердин графикалык көрүнүшү
Агымдар негизинен эки түргө бөлүнөт:
Киришүү
Объектти сериалдаштыруу – бул an objectтин өзүнүн толук көчүрмөсүн жана чыгаруу агымын (мисалы, тышкы файлга) колдонуу менен шилтеме кылган башка an objectтерди сактоо мүмкүнчүлүгү. Ошентип, an objectти серияланган (сакталган) көчүрмөдөн бир аз кийинчерээк керек болгондо кайра түзсө болот. Объектти сериялаштыруу, JDK 1.1де киргизилген жаңы функция, тармак аркылуу сактоо же берүү үчүн топторду же айрым an objectтерди бит агымына же byte массивине айландыруу функциясын камсыз кылат. Жана айтылгандай, берилген бит агымы же byte массивдери кайра Java an objectтерине айландырылат.ObjectInputStream
Бул негизинен жана класстардын аркасында автоматтык түрдө болот ObjectOutputStream
. Программист Serializable
классты түзүүдө интерфейсти ишке ашыруу аркылуу бул функцияны ишке ашырууну чечиши мүмкүн. Сериялаштыруу процесси an objectти маршалдаштыруу деп да белгилүү, ал эми сериялаштыруу unmarshaling деп аталат . Сериялаштыруу - бул an objectке өзүнүн көчүрмөсүн жана an object шилтеме кылган бардык башка an objectтерди тышкы файлга сактоого мүмкүндүк берүүчү механизм ObjectOutputStream
. Сакталган an objectтер маалымат структуралары, диаграммалар, класс an objectтери JFrame
же алардын түрүнө карабастан башка an objectтер болушу мүмкүн. Ошол эле учурда, сериялаштыруу an objectтин кандай түрү жөнүндө маалыматты сактайт, ошондуктан кийинчерээк сериядан ажыратылганда, ал маалымат an objectтин так түрүн кайра жаратуу үчүн колдонулат. Ошентип, сериялаштыруу төмөнкү мүмкүнчүлүктөрдү камсыз кылат:
- Объекттерди сактоо системасы, б.а.: алардын касиеттерин тышкы файлга, дискке же маалымат базасына сактоо.
- Алыскы proceduresаларды чакыруу системасы.
- Объектти бөлүштүрүү системасы, мисалы, COM, COBRA сыяктуу программалык камсыздоо компоненттеринде.
- Убакыттын өтүшү менен өзгөрүлмө маалыматтардагы өзгөрүүлөрдү аныктоо системасы.
Агымдар:
Ар бир программа өз маалыматтарын сактоочу жайга же түтүккө жазышы керек жана ар бир программа түтүктөн же сактагыч жеринен маалыматтарды окушу керек. Java тorнде программалар жазылган жана маалымат окуган бул каналдар Агымдар (Stream
) деп аталат .
- *Агымдар деп аталган byte агым класстары
- *Окурман жана *Жазуучу деп аталган каармандардын агымы класстары
Туруктуулук
Объекттин туруктуулугу - бул an objectтин жашоо же, башкача айтканда, программаны аткарууда "жашоо" жөндөмдүүлүгү. Бул иштөө убагында түзүлгөн an object JVM тазалагычы тарабынан ал an object колдонулбай калган сайын жок кылынат дегенди билдирет. Бирок персистенттик API ишке ашырылса, бул an objectтер JVM тазалагыч тарабынан жок кылынbyte, тескерисинче, аларга "жашоо" уруксаты берилет, бул дагы тиркеме кийинки жолу ишке киргизилгенде аларга кирүү мүмкүнчүлүгүн берет. Башка сөз менен айтканда, туруктуулук иштеп жаткан тиркеменин иштөө мөөнөтүнөн көз карандысыз an object үчүн бир өмүр бар экенин билдирет. Туруктуулукту ишке ашыруунун бир жолу an objectтерди тышкы файлдын же маалымат базасынын бир жеринде сактоо, андан кийин бул файлдарды же маалымат базасын булак катары колдонуу менен аларды кийинчерээк калыбына келтирүү. Бул жерде сериализация ишке кирет. Ар кандай туруктуу эмес an object JVM иштеп турганда бар. Сериялаштырылган an objectтер жөн гана агымга айландырылган an objectтер, алар андан кийин тышкы файлга сакталат же сактоо жана калыбына келтирүү үчүн тармак аркылуу өткөрүлөт.Serializable интерфейсин ишке ашыруу
java.io.Serializable
Ар бир класс ошол класстын an objectтерин сериялаштыруу үчүн интерфейсти ишке ашырышы керек . Интерфейстин Serializable
методдору жок жана классты сериялаштырыла турган катары аныктоо үчүн гана белгилейт. Серияланган класс an objectинин талаалары гана сакталышы мүмкүн. Методдор же конструкторлор серияланган агымдын бир бөлүгү катары сакталbyte. Эгерде кандайдыр бир an object башка an objectке шилтеме катары иштесе, анда ал an objectтин классы интерфейсти ишке ашырса, ал an objectтин талаалары да серияланат Serializable
. Башкача айтканда, бул an objectтин графиги толугу менен сериялаштырылат. Объекттин графиги даракты же an objectтин жана анын субan objectилеринин талааларынын структурасын камтыйт. Интерфейсти ишке ашырууга жардам берген эки негизги класс Seriliazable
:
ObjectInputStream
ObjectOutputStream
import java.io.*;
public class RandomClass implements Serializable {
// Генерация рандомного значения
private static int r() {
return (int)(Math.random() * 10);
}
private int data[];
// Конструктор
public RandomClass() {
datafile = new int[r()];
for (int i=0; i<datafile.length; i++)
datafile[i]=r();
}
public void printout() {
System.out.println("This RandomClass has "+datafile.length+" random integers");
for (int i=0; i<datafile.length; i++) {
System.out.print(datafile[i]+":");
System.out.println();
}
}
Жогорудагы codeдо, анткени сериялаштырыла турган класс түзүлгөн сериялаштыруу интерфейси менен "белгиленген". Класс анын бир нускасы түзүлгөндө кокус бүтүн сандардын массивин түзөт. Төмөндөгү code агымдын жардамы менен an objectтерди жазуу мүмкүнчүлүгүн көрсөтөт ObjectOutputStream
. Программада бүтүн сандардын массивдери бар, бирок сериялаштыруу үчүн анын ички an objectилерин кайталоонун кереги жок. Интерфейс Seriliazable
муну автоматтык түрдө аткарат. Листинг 2. Файлга чыгаруу үчүн an objectтерди сериялаштыруунун жөнөкөй мисалы
import java.io.*;
import java.util.*;
public class OutSerialize {
public static void main (String args[]) throws IOException {
RandomClass rc1 = new RandomClass();
RandomClass rc2 = new RandomClass();
//создание цепи потоков с потоком вывода an object в конце
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("objects.dat"));
Date now = new Date(System.currentTimeMillis());
//java.util.* был импортирован для использования класса Date
out.writeObject(now);
out.writeObject(rc1);
out.writeObject(rc2);
out.close();
System.out.println("I have written:");
System.out.println("A Date object: "+now);
System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
}
}
Төмөндөгү code класстын мүмкүнчүлүктөрүн көрсөтөт ObjectInputStream
, ал тышкы файлдан программага серияланган маалыматтарды окуйт. Объекттер файлга жазылган тартипте окулат. Листинг 3. Сериялаштырылган an objectтерди окуу же Сериядан чыгаруу
import java.io.*;
import java.util.*;
public class InSerialize {
public static void main (String args[]) throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream (new FileInputStream("objects.dat"));
Date d1 = (Date)in.readObject();
RandomClass rc1 = (RandomClass)in.readObject();
RandomClass rc2 = (RandomClass)in.readObject();
System.out.println("I have read:");
System.out.println("A Date object: "+d1);
System.out.println("Two Group of randoms");
rc1.printout();
rc2.printout();
}
}
Дээрлик бардык Java класстарын, анын ичинде AWT класстарын сериялаштырууга болот. Терезе болгон рамка графикалык компоненттердин жыйындысын камтыйт. Эгерде кадр сериалдаштырылса, сериялаштыруу кыймылдаткычы мунун камын көрүп, анын бардык компоненттерин жана берorштерин (позициясы, мазмуну ж.б.) сериялаштырат. Кээ бир Java класс an objectтерин сериялаштыруу мүмкүн эмес, анткени аларда эфемердик операциялык тутумдун ресурстарына шилтеме берген маалыматтар бар. Мисалы, класстар java.io.FileInputStream
жана java.lang.Thread
. Эгерде an object сериялаштырылбаган элементтерге шилтемелерди камтыса, бүтүндөй сериялаштыруу операциясы ишке ашпай калат жана өзгөчө кырдаал ташталат NotSerializableException
. Эгерде кандайдыр бир an object серияланбаган an objectтин шилтемесине кайрылса, анда аны transient ачкыч сөзү менен сериялаштырууга болот . Листинг 4. Transient ачкыч сөзүн колдонуу менен сериализациялануучу an objectтерди түзүү
public class Sclass implements Serializable{
public transient Thread newThread;
//помните, что поток(поток параллельного исполнения) по умолчанию не сериализуемый класс
private String studentID;
private int sum;
}
Сериялаштыруудагы коопсуздук
Javaдагы классты сериялаштыруу анын бардык маалыматтарын агым аркылуу тышкы файлга же маалымат базасына өткөрүп берүүнү камтыйт. Каалаган убакта сериялаштыра турган маалыматтарды чектей алабыз. Муну жасоонун эки жолу бар:- Өтмө деп жарыяланган ар бир класс параметри серияланbyte (демейки боюнча, бардык класс параметрлери сериялаштырылган)
- Же, биз сериялаштыргыбыз келген класстын ар бир параметри тег менен белгиленген
Externalizable
(демейки боюнча, эч кандай параметр сериялаштырылbyte).
ObjectOutputStream
деп белгиленсе, маалымат талаасы an objectке чакырылганда сериялаштырылbyte . Мисалы: . Экинчи жагынан, an objectтин берorштерин сериялаштырылуучу катары ачык жарыялоо үчүн, классты ошол an objectтин берorштерин ачык жазып жана окуйт деп белгилешибиз керек.private transient String password
ExternalizablewriteExternal
readExteranl
Корутунду
Объектти сериалдаштыруунун өзгөчөлүгү маалыматтарды берүү жолу катары көптөгөн бөлүштүрүлгөн системаларда колдонулат. Бирок сериалдаштыруу жашыруун деталдарды ачып берет, ошентип абстракттуу маалымат түрлөрүнүн аныктыгын жок кылат, бул өз кезегинде инкапсуляцияны жок кылат. Ошол эле учурда, серияланган an objectтин маалыматтары баштапкы, оригиналдуу an objectте болгон маалыматтар экенин билүү жагымдуу. Бул ошондой эле интерфейсти ишке ашыруу жана codeдун бир нече саптары колдонулса дагы,ObjectInputValidation
методду жокко чыгаруу үчүн сонун мүмкүнчүлүк. validateObject()
Эгерде an object табылбаса, анда биз тийиштүү түрдө өзгөчөлүктү ыргыта алабыз InvalidObjectException
. Оригиналдуу макала: Java'да сериалдаштыруу кантип иштейт
GO TO FULL VERSION