betacode

Руководство Java ObjectInputStream

  1. ObjectInputStream
  2. Example 1
  3. readFields()
  4. readUnshared()

1. ObjectInputStream

ObjectInputStream - это подкласс класса InputStream, который управляет объектом InputStream и предоставляет методы для чтения примитивных данных (primitive data) или объекта из InputStream, которым он управляет.
public class ObjectInputStream
          extends InputStream implements ObjectInput, ObjectStreamConstants
ObjectInputStream используется для чтения источников данных, записанных ObjectOutputStream.
ObjectInputStream methods
public boolean readBoolean() throws IOException  
public byte readByte() throws IOException  
public int readUnsignedByte() throws IOException  
public char readChar() throws IOException  
public short readShort() throws IOException  
public int readUnsignedShort() throws IOException  
public int readInt() throws IOException  
public long readLong() throws IOException  
public float readFloat() throws IOException  
public double readDouble() throws IOException  
public void readFully(byte[] buf) throws IOException  
public void readFully(byte[] buf, int off, int len) throws IOException  
public int skipBytes(int len) throws IOException  
public String readUTF() throws IOException  
public final ObjectInputFilter getObjectInputFilter()  
public final void setObjectInputFilter(ObjectInputFilter filter)  

public final Object readObject() throws IOException, ClassNotFoundException  
public Object readUnshared() throws IOException, ClassNotFoundException  
public void defaultReadObject() throws IOException, ClassNotFoundException  
public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException  
public void registerValidation(ObjectInputValidation obj, int prio) throws NotActiveException, InvalidObjectException

protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException  
protected Object readObjectOverride() throws IOException, ClassNotFoundException  
protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException  
protected Object resolveObject(Object obj) throws IOException  
protected boolean enableResolveObject(boolean enable) throws SecurityException  
protected void readStreamHeader() throws IOException, StreamCorruptedException  
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException  

String readTypeString() throws IOException

// Methods inherited from InputStream:

public int read() throws IOException  
public int read(byte[] buf, int off, int len) throws IOException  
public int available() throws IOException  
public void close() throws IOException
ObjectInputStream​ constructors
public ObjectInputStream​(InputStream in)

2. Example 1

В этом примере мы запишем объекты Employee в файл, а затем будем использовать ObjectInputStream для чтения файла.
Класс Employee должен реализовать (implement) интерфейс Serializable, это необходимо для того, чтобы его можно было записать в ObjectOutputStream.
Employee.java
package org.o7planning.beans;
 
import java.io.Serializable;
 
public class Employee implements Serializable {
 
    private static final long serialVersionUID = 1L;
 
    private String fullName;
    private float salary;
 
    public Employee(String fullName, float salary) {
        this.fullName = fullName;
        this.salary = salary;
    }
 
    public String getFullName() {
        return fullName;
    }
 
    public void setFullName(String firstName) {
        this.fullName = firstName;
    }
 
    public float getSalary() {
        return salary;
    }
 
    public void setSalary(float lastName) {
        this.salary = lastName;
    }
}
Затем используем ObjectOutputStream для записи объектов Employee в файл.
WriteEmployeeDataEx.java
package org.o7planning.objectinputstream.ex;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Date;

import org.o7planning.beans.Employee;

public class WriteEmployeeDataEx {

    // Windows: C:/Data/test/employees.data
    private static String file_path = "/Volumes/Data/test/employees.data";

    public static void main(String[] args) throws IOException {
        File outFile = new File(file_path);

        outFile.getParentFile().mkdirs();

        Employee e1 = new Employee("Tom", 1000f);
        Employee e2 = new Employee("Jerry", 2000f);
        Employee e3 = new Employee("Donald", 1200f);

        Employee[] employees = new Employee[] { e1, e2, e3 };

        OutputStream os = new FileOutputStream(outFile);
        ObjectOutputStream oos = new ObjectOutputStream(os);

        System.out.println("Writing file: " + outFile.getAbsolutePath());

        oos.writeObject(new Date());
        oos.writeUTF("Employee data"); // Some informations.

        oos.writeInt(employees.length); // Number of Employees

        for (Employee e : employees) {
            oos.writeObject(e);
        }
        oos.close();
        System.out.println("Finished!");
    }
}
После запуска класса WriteEmployeeDataEx мы получаем файл с запутанным содержимым
Наконец, используем ObjectInputStream для чтения файла, только что записанного на предыдущем шаге.
ReadEmployeeDataEx.java
package org.o7planning.objectinputstream.ex;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.util.Date;

import org.o7planning.beans.Employee;

public class ReadEmployeeDataEx {

    // Windows: C:/Data/test/employees.data
    private static String file_path = "/Volumes/Data/test/employees.data";

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File inFile = new File(file_path);
 

        InputStream is = new FileInputStream(inFile);
        ObjectInputStream ois = new ObjectInputStream(is);

        System.out.println("Reading file: " + inFile.getAbsolutePath());
        System.out.println();

        Date date = (Date) ois.readObject();
        String info = ois.readUTF();
        
        System.out.println(date);
        System.out.println(info);
        System.out.println();
        
        int employeeCount = ois.readInt();
        
        for(int i=0; i< employeeCount; i++) {
            Employee e = (Employee) ois.readObject();
            System.out.println("Employee Name: " + e.getFullName() +" / Salary: " + e.getSalary());
        }
        ois.close();
    }
}
Output:
Reading file: /Volumes/Data/test/employees.data

Sat Mar 20 18:54:24 KGT 2021
Employee data

Employee Name: Tom / Salary: 1000.0
Employee Name: Jerry / Salary: 2000.0
Employee Name: Donald / Salary: 1200.0

3. readFields()

Предположим, вы используете ObjectInputStream для чтения объекта GameSetting из файла. В то же время, читая объект GameSetting, вы хотите изменить значения некоторых его полей (field).
GameSetting.java
package org.o7planning.beans;

import java.io.IOException;
import java.io.ObjectInputStream;

public class GameSetting implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    private int sound;
    private int bightness;
    private String difficultyLevel;

    private String userNote;

    public GameSetting(int sound, int bightness, String difficultyLevel, String userNote) {
        this.sound = sound;
        this.bightness = bightness;
        this.difficultyLevel = difficultyLevel;
        this.userNote = userNote;
    }

    public int getSound() {
        return sound;
    }

    public int getBightness() {
        return bightness;
    }

    public String getDifficultyLevel() {
        return difficultyLevel;
    }

    public String getUserNote() {
        return userNote;
    }

    // Do not change name and parameter of this method.
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        ObjectInputStream.GetField fields = in.readFields();

        this.sound = fields.get("sound", 50);
        this.bightness = fields.get("bightness", 50);
        
        // Edit fields
        this.difficultyLevel = (String) fields.get("difficultyLevel", "Easy"); // Default
        if (this.difficultyLevel == null) {
            this.difficultyLevel = "Easy";
        }

        this.userNote = (String) fields.get("userNote", "Have fun!"); // Default
        if (this.userNote == null) {
            this.userNote = "Have fun!";
        }
    }
}
ObjectInputStream_readFields.java
package org.o7planning.objectinputstream.ex;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Date;

import org.o7planning.beans.GameSetting;

public class ObjectInputStream_readFields {

    // Windows: C:/Data/test/game_setting.data
    private static String file_path = "/Volumes/Data/test/game_setting.data";

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        
        GameSetting setting = new GameSetting(10, 80, null, null);

        writeGameSetting(setting);
        readGameSetting();
    }

    private static void writeGameSetting(GameSetting setting) throws IOException {
        File file = new File(file_path);
        file.getParentFile().mkdirs();

        OutputStream os = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(os);

        // Write a String
        oos.writeUTF("Game Settings, Save at " + new Date());
        // Write Object
        oos.writeObject(setting);

        oos.close();
    }

    private static void readGameSetting() throws IOException, ClassNotFoundException {
        File file = new File(file_path);
        file.getParentFile().mkdirs();

        InputStream is = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(is);

        // Read a String
        String info = ois.readUTF();

        // Read fields
        GameSetting setting = (GameSetting) ois.readObject();

        System.out.println("sound: " + setting.getSound());
        System.out.println("bightness: " + setting.getBightness());
        System.out.println("difficultyLevel: " + setting.getDifficultyLevel());
        System.out.println("userNote: " + setting.getUserNote());  // null.

        ois.close();
    }
}
Output:
sound: 10
bightness: 80
difficultyLevel: Easy
userNote: Have fun!

4. readUnshared()

Метод ObjectInputStream.readUnshared() используется для чтения объекта, записанного методом ObjectOutputStream.writeUnshared(Object).
ObjectInputStream_readUnshared​.java
package org.o7planning.objectinputstream.ex;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;

public class ObjectInputStream_readUnshared​ {

    // Windows: C:/Data/test/test1.data
    private static String file_path = "/Volumes/Data/test/test.data";

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        writeUnsharedTest();
        
        readUnsharedTest();
    }
    
    private static void writeUnsharedTest() throws IOException  {
        File file = new File(file_path);
        file.getParentFile().mkdirs();
        
        ArrayList<String> list = new ArrayList<String>();
        list.add("One");
        list.add("Two");
        
        OutputStream os = new FileOutputStream(file);
        ObjectOutputStream oos = new ObjectOutputStream(os);
        
        oos.writeUnshared(list); // Write the first time
        oos.writeUnshared(list); // Write the second time
        oos.close();
    }

    @SuppressWarnings({ "unchecked" })
    private static void readUnsharedTest() throws IOException, ClassNotFoundException  {
        File file = new File(file_path);
        
        ArrayList<String> list = new ArrayList<String>();
        list.add("One");
        list.add("Two");
        
        InputStream is = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(is);
        
        ArrayList<String> list1 = (ArrayList<String>) ois.readUnshared();  
        ArrayList<String> list2 = (ArrayList<String>) ois.readUnshared();  
        
        System.out.println("list1 == list2? " + (list1 == list2));
        
        ois.close();
    }
}
Output:
list1 == list2? false
См.Объяснение метода ObjectOutputStream.writeUnshared(Object):

Руководства Java IO

Show More