Java serialization to file

File Handling in Java: Object Serialization

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Object serialization is a mechanism to manipulate Java objects (POJO) to and from a stream of bytes. Serialization, in particular, refers to its representation as a sequence of bytes. These bytes contains an object’s data, type information of the object, and also the type of data content in the object. An object, once serialized, can be persisted in a file or used in an application that communicate via network. The reverse process, called deserialization, is used to re-create the same object in memory from the stream of bytes. Data communication via objects rather than a sequence of bytes is convenient and efficient in both file handling and network communication. In this article, we shall explore the serialization/deserialization process with the help of a file handling mechanism. Conceptually, serialization in network programming also follows the same idea.

The Need for Objects to be Serialized

Because serialization converts an object to a stream of bytes and deserialization re-creates the object in memory, the basic idea of operation remains the same as it in object persistence or a network transfer. Note that serialization is not the only answer to transform objects into a stream of bytes but a standard and convenient way to do so. Otherwise, one had to re-create objects from the sequence of bytes from scratch in every application. For example, in a simple file handling program without serialization, when an instance variable for a certain object were to output to a disk file, the type information of object data gets lost. That means, a value, say “55,” is read back from a file, there is no way to tell if the value came from a Integer, a String, or a Double. Also, it is not possible to determine whether the separator used in the file between values is a space character or something else. Are there single records in a line or multiple records per line in the file? This information is necessary for re-creating the object, especially by the program that reads the data. If, however, the program knows the object type exactly, perhaps it’s all right and possible to read into the correct object. But in practice, it’s often not so. It is not possible to know precisely how data is stored in a file unless type information of the object with its content are also maintained systematically in the file.

Implementing Object Serialization

Serialization of a object starts with implementing a java.io.Serialization interface. Then, to work with the serialized object, we have to initialize the ObjectInputStream and ObjectOutputStream objects with stream objects. ObjectInputStream implements the ObjectInput interface and ObjectOutputStream implements the ObjectOutput interface, respectively. These objects read from and write to file stream objects, such as FileInputStream and FileOutputStream, respectively (in case of file handling). Both file stream and object streams are basically stream objects wrapped into one another for the purpose of object persistence in a file. The stream object being created wraps another stream object specified as a constructor argument; for example, to wrap FileOuputStream in an ObjectOutputStream, we pass a FileOutputStream object to the ObjectOutputStream‘s constructor. The method writeObject, responsible for streaming object bytes, takes an object that implements a Serializable interface as an argument. In a way, an object that implements a Serializable interface is tagged to transform into a sequence of bytes retaining not only the object values but also the type information of the object and its content as well. Serialization acts as a tagging interface and does not have any method of its own. ObjectInputStream/ObjectOuputStream will not input/output an object unless it is marked serializable. A serializable class must ensure that the instance variables of the class must also be serializable; if this is not so, they must be declared as transient to indicate non serializability and they should be ignored during the serializability process. This situation occurs in cases such as in serializing reference types. All primitive types of variables in Java are serializable including array objects. However, for some reference types or an array of reference types, it may occur that the referred object is not serializable.

Читайте также:  Ваша версия php устарела пожалуйста обновите ее

Object Serialization in a Sequential Access File

Let us create and manipulate a simple sequential access file using object serialization to delineate the idea further.

This is our serialized POJO implementing a java.io.Serializable interface.

public class ProductRecord implements Serializable< private int productCode; private String composition; private String productName; private String company; private int stockQuantity; private int reorderLevel; private float unitPrice; // . constructors, getters,and setters >

This class shows how to implement ObjectInputStream and ObjectOutputStream objects to read and write a serialized object into a file. The method writeToFile/readFromFile implements the file input/output mechanism from a stream of bytes transformed by ObjectOutputStream/ObjectInputStream.

public class ProductFileStream < public void writeToFile(List list, String file) < ObjectOutputStream outStream = null; try < outStream = new ObjectOutputStream(new FileOutputStream(file)); for (ProductRecord p : list) < outStream.writeObject(p); >> catch (IOException ioException) < System.err.println("Error opening file."); > catch (NoSuchElementException noSuchElementException) < System.err.println("Invalid input."); > finally < try < if (outStream != null) outStream.close(); > catch (IOException ioException) < System.err.println("Error closing file."); > > > public List readFromFile(String file) < Listlist = new ArrayList<>(); ObjectInputStream inputStream = null; try < inputStream = new ObjectInputStream(new FileInputStream(file)); while (true) < ProductRecord p = (ProductRecord) inputStream.readObject(); list.add(p); >> catch (EOFException eofException) < return list; > catch (ClassNotFoundException classNotFoundException) < System.err.println("Object creation failed."); > catch (IOException ioException) < System.err.println("Error opening file."); > finally < try < if (inputStream != null) inputStream.close(); > catch (IOException ioException) < System.err.println("Error closing file."); > > return list; > >

Testing object serialization in a file with dummy data:

public class ProductFile< public static void main(String[] args) < String filePath = "/home/mano/temp/product.dat"; Listlist = new ArrayList<>(); list.add(new ProductRecord(111, "Amitryptyline", "Amiline", "Torrent", 10, 5, 13.35f)); // . dummy data list.add(new ProductRecord(191, "Amlodipine", "Amdepin", "ZydusCadila", 18, 6, 20.90f)); ProductFileStream pf=new ProductFileStream(); pf.writeToFile(list, filePath); List products=pf.readFromFile(filePath); printlist(products); > public static void printlist(List list) < System.out.printf("%-7s%-20s%-20s%-20s%-10s%-10s%-10sn", "Code", "Generic", "Name", "Company", "Stock", "Reorder", "Unit Price"); for (ProductRecord p : list) < System.out.printf("%-7d%-20s%-20s%-20s%-10d%-10d%.2fn", p.getProductCode(), p.getComposition(), p.getProductName(), p.getCompany(), p.getStockQuantity(), p.getReorderLevel(), p.getUnitPrice()); > > >

Conclusion

The core idea of serialization is to transform an object into a stream of bytes and deserialization is to re-create the object back from the stream of bytes; that’s it! Java provides a standard mechanism to achieve it through java.io.Serialization. File handling and Network programs are the most common but not the only example that require such a mechanism. Storing images or image processing is also another area where serialization may come in handy. Try your hand at it and explore its power in different area of programming. Serialization in Network programming is an interesting area. Do comment if you are inquisitive; together, we’ll explore it.

Источник

Читайте также:  Java nio file list files

Java serialization to file

Сериализация представляет процесс записи состояния объекта в поток, соответственно процесс извлечения или восстановления состояния объекта из потока называется десериализацией . Сериализация очень удобна, когда идет работа со сложными объектами.

Интерфейс Serializable

Сразу надо сказать, что сериализовать можно только те объекты, которые реализуют интерфейс Serializable . Этот интерфейс не определяет никаких методов, просто он служит указателем системе, что объект, реализующий его, может быть сериализован.

Сериализация. Класс ObjectOutputStream

Для сериализации объектов в поток используется класс ObjectOutputStream . Он записывает данные в поток.

Для создания объекта ObjectOutputStream в конструктор передается поток, в который производится запись:

ObjectOutputStream(OutputStream out)

Для записи данных ObjectOutputStream использует ряд методов, среди которых можно выделить следующие:

  • void close() : закрывает поток
  • void flush() : очищает буфер и сбрасывает его содержимое в выходной поток
  • void write(byte[] buf) : записывает в поток массив байтов
  • void write(int val) : записывает в поток один младший байт из val
  • void writeBoolean(boolean val) : записывает в поток значение boolean
  • void writeByte(int val) : записывает в поток один младший байт из val
  • void writeChar(int val) : записывает в поток значение типа char, представленное целочисленным значением
  • void writeDouble(double val) : записывает в поток значение типа double
  • void writeFloat(float val) : записывает в поток значение типа float
  • void writeInt(int val) : записывает целочисленное значение int
  • void writeLong(long val) : записывает значение типа long
  • void writeShort(int val) : записывает значение типа short
  • void writeUTF(String str) : записывает в поток строку в кодировке UTF-8
  • void writeObject(Object obj) : записывает в поток отдельный объект

Эти методы охватывают весь спектр данных, которые можно сериализовать.

Например, сохраним в файл один объект класса Person:

import java.io.*; public class Program < public static void main(String[] args) < try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.dat"))) < Person p = new Person("Sam", 33, 178, true); oos.writeObject(p); >catch(Exception ex) < System.out.println(ex.getMessage()); >> > class Person implements Serializable < private String name; private int age; private double height; private boolean married; Person(String n, int a, double h, boolean m)< name=n; age=a; height=h; married=m; >String getName() int getAge() < return age;>double getHeight() boolean getMarried() >

Десериализация. Класс ObjectInputStream

Класс ObjectInputStream отвечает за обратный процесс — чтение ранее сериализованных данных из потока. В конструкторе он принимает ссылку на поток ввода:

ObjectInputStream(InputStream in)

Функционал ObjectInputStream сосредоточен в методах, предназначенных для чтения различных типов данных. Рассмотрим основные методы этого класса:

  • void close() : закрывает поток
  • int skipBytes(int len) : пропускает при чтении несколько байт, количество которых равно len
  • int available() : возвращает количество байт, доступных для чтения
  • int read() : считывает из потока один байт и возвращает его целочисленное представление
  • boolean readBoolean() : считывает из потока одно значение boolean
  • byte readByte() : считывает из потока один байт
  • char readChar() : считывает из потока один символ char
  • double readDouble() : считывает значение типа double
  • float readFloat() : считывает из потока значение типа float
  • int readInt() : считывает целочисленное значение int
  • long readLong() : считывает значение типа long
  • short readShort() : считывает значение типа short
  • String readUTF() : считывает строку в кодировке UTF-8
  • Object readObject() : считывает из потока объект
Читайте также:  Www online moek ru person peredacha pokazaniya html

Например, извлечем выше сохраненный объект Person из файла:

import java.io.*; public class Program < public static void main(String[] args) < try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.dat"))) < Person p=(Person)ois.readObject(); System.out.printf("Name: %s \t Age: %d \n", p.getName(), p.getAge()); >catch(Exception ex) < System.out.println(ex.getMessage()); >> >

Теперь совместим сохранение и восстановление из файла на примере списка объектов:

import java.io.*; import java.util.ArrayList; public class Program < //@SuppressWarnings("unchecked") public static void main(String[] args) < String filename = "people.dat"; // создадим список объектов, которые будем записывать ArrayListpeople = new ArrayList(); people.add(new Person("Tom", 30, 175, false)); people.add(new Person("Sam", 33, 178, true)); try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) < oos.writeObject(people); System.out.println("File has been written"); >catch(Exception ex) < System.out.println(ex.getMessage()); >// десериализация в новый список ArrayList newPeople= new ArrayList(); try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) < newPeople=((ArrayList)ois.readObject()); > catch(Exception ex) < System.out.println(ex.getMessage()); >for(Person p : newPeople) System.out.printf("Name: %s \t Age: %d \n", p.getName(), p.getAge()); > > class Person implements Serializable < private String name; private int age; private double height; private boolean married; Person(String n, int a, double h, boolean m)< name=n; age=a; height=h; married=m; >String getName() int getAge() < return age;>double getHeight() boolean getMarried() >

Исключение данных из сериализации

По умолчанию сериализуются все переменные объекта. Однако, возможно, мы хотим, чтобы некоторые поля были исключены из сериализации. Для этого они должны быть объявлены с модификатором transient . Например, исключим из сериализации объекта Person переменные height и married:

class Person implements Serializable < private String name; private int age; private transient double height; private transient boolean married; Person(String n, int a, double h, boolean m)< name=n; age=a; height=h; married=m; >String getName() int getAge() < return age;>double getHeight() boolean getMarried() >

Источник

Оцените статью