Thứ Năm, 9 tháng 8, 2018

Java - Tuần tự hóa

Tổng quan :

Học lập trình Java cung cấp một cơ chế, được gọi là serialization đối tượng, nơi một đối tượng có thể được biểu diễn như một chuỗi các byte bao gồm dữ liệu của đối tượng cũng như thông tin về kiểu của đối tượng và các kiểu dữ liệu được lưu trữ trong đối tượng.

ảnh minh họa


Sau khi một đối tượng tuần tự được ghi vào một tệp, nó có thể được đọc từ tệp và được deserialized, thông tin kiểu và byte đại diện cho đối tượng và dữ liệu của nó có thể được sử dụng để tạo lại đối tượng trong bộ nhớ.

Ấn tượng nhất là toàn bộ quá trình là JVM độc lập, có nghĩa là một đối tượng có thể được tuần tự hóa trên một nền tảng và được deserialized trên một nền tảng hoàn toàn khác.

Các lớp ObjectInputStream và ObjectOutputStream là các luồng cao cấp có chứa các phương thức để tuần tự hóa và deserializing một đối tượng.

Lớp Object Output Stream chứa nhiều phương thức ghi để viết các kiểu dữ liệu khác nhau, nhưng một phương thức đặc biệt nổi bật.

public final void writeObject(Object x) throws IOExceptionPhương thức trên sẽ tuần tự hóa một đối tượng và gửi nó tới luồng đầu ra. Tương tự, lớp ObjectInputStream chứa phương thức sau để deserializing một đối tượng

public final Object readObject() throws IOException, ClassNotFoundException

Phương thức này lấy đối tượng tiếp theo ra khỏi luồng và deserializes nó. Giá trị trả về là Object, vì vậy bạn sẽ cần phải đưa nó vào kiểu dữ liệu thích hợp của nó.

Để chứng minh cách serialization hoạt động như thế nào trong Java, tôi sẽ sử dụng class Employee mà chúng ta đã thảo luận trong cuốn sách. Giả sử rằng chúng ta có class Employee sau, nó thực hiện giao diện Serializable

Thí dụ

public class Employee implements java.io.Serializable {
   public String name;
   public String address;
   public transient int SSN;
   public int number;
   
   public void mailCheck() {
      System.out.println("Mailing a check to " + name + " " + address);
   }
}
Lưu ý rằng để một lớp được nối tiếp thành công, phải đáp ứng hai điều kiện

Lớp phải triển khai giao diện java.io.Serializable.

Tất cả các trường trong lớp phải được tuần tự hóa. Nếu một trường không được tuần tự hóa, trường đó phải được đánh dấu thoáng qua .

Nếu bạn tò mò muốn biết một lớp Java chuẩn có thể tuần tự hóa hay không, hãy kiểm tra tài liệu cho lớp đó. Bài kiểm tra rất đơn giản: Nếu lớp thực hiện java.io.Serializable, thì nó có thể được tuần tự hóa; nếu không, nó không phải.

Nối tiếp một đối tượng

Lớp ObjectOutputStream được sử dụng để tuần tự hóa một đối tượng. Chương trình SerializeDemo sau đây instantiates một đối tượng Employee và serializes nó vào một tập tin.

Khi chương trình được thực hiện xong, một tệp có tên employee.ser được tạo. Chương trình không tạo ra bất kỳ đầu ra nào, nhưng nghiên cứu mã và cố gắng xác định chương trình đang làm gì.

Lưu ý - Khi tuần tự hóa một đối tượng vào một tệp, quy ước chuẩn trong Java là cung cấp cho tệp một phần mở rộng .ser .

Thí dụ
import java.io.*;
public class SerializeDemo {

   public static void main(String [] args) {
      Employee e = new Employee();
      e.name = "Reyan Ali";
      e.address = "Phokka Kuan, Ambehta Peer";
      e.SSN = 11122333;
      e.number = 101;
      
      try {
         FileOutputStream fileOut =
         new FileOutputStream("/tmp/employee.ser");
         ObjectOutputStream out = new ObjectOutputStream(fileOut);
         out.writeObject(e);
         out.close();
         fileOut.close();
         System.out.printf("Serialized data is saved in /tmp/employee.ser");
      } catch (IOException i) {
         i.printStackTrace();
      }
   }
}

Deserializing một đối tượng

Chương trình DeserializeDemo sau deserializes đối tượng Employee được tạo trong chương trình SerializeDemo. Nghiên cứu chương trình và cố gắng xác định đầu ra của nó -
Thí dụ
import java.io.*;
public class DeserializeDemo {

   public static void main(String [] args) {
      Employee e = null;
      try {
         FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
         ObjectInputStream in = new ObjectInputStream(fileIn);
         e = (Employee) in.readObject();
         in.close();
         fileIn.close();
      } catch (IOException i) {
         i.printStackTrace();
         return;
      } catch (ClassNotFoundException c) {
         System.out.println("Employee class not found");
         c.printStackTrace();
         return;
      }
      
      System.out.println("Deserialized Employee...");
      System.out.println("Name: " + e.name);
      System.out.println("Address: " + e.address);
      System.out.println("SSN: " + e.SSN);
      System.out.println("Number: " + e.number);
   }
}

Điều này sẽ tạo ra kết quả sau 

Đầu ra
Deserialized Employee...
Name: Reyan Ali
Address:Phokka Kuan, Ambehta Peer
SSN: 0
Number:101

Dưới đây là những điểm quan trọng cần lưu ý

Khối try / catch cố gắng nắm bắt một ClassNotFoundException, được khai báo bởi phương thức readObject (). Để một JVM có thể deserialize một đối tượng, nó phải có khả năng tìm bytecode cho lớp đó. Nếu JVM không thể tìm thấy một lớp trong quá trình deserialization của một đối tượng, nó sẽ ném ra một ClassNotFoundException.

Lưu ý rằng giá trị trả về của readObject () được truyền tới tham chiếu Employee.

Giá trị của trường SSN là 11122333 khi đối tượng được tuần tự hóa, nhưng vì trường là tạm thời, giá trị này không được gửi đến luồng đầu ra. Trường SSN của đối tượng Employer deserialized là 0.

Không có nhận xét nào:

Đăng nhận xét

Lập trình Java - Ngoại lệ

Một ngoại lệ (hoặc sự kiện đặc biệt) là một vấn đề phát sinh trong quá trình thực hiện chương trình. Khi xảy ra Ngoại lệ , luồng bình thường...