betacode

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

  1. ObjectOutputStream
  2. Example 1
  3. Example 2
  4. writeFields()
  5. writeUnshared​(Object)

1. ObjectOutputStream

ObjectOutputStream - это подкласс класса OutputStream, который управляет объектом OutputStream и предоставляет методы для записи примитивных данных (primitive data) или объектов в OutputStream, которым он управляет.
public class ObjectOutputStream
              extends OutputStream implements ObjectOutput, ObjectStreamConstants
ObjectInputStream используется для чтения источников данных, созданных ObjectOutputStream:
ObjectOutputStream Methods
public final void writeObject(Object obj) throws IOException
public void writeBoolean(boolean val) throws IOException
public void writeByte(int val) throws IOException
public void writeShort(int val) throws IOException
public void writeChar(int val) throws IOException
public void writeInt(int val) throws IOException
public void writeLong(long val) throws IOException
public void writeFloat(float val) throws IOException
public void writeDouble(double val) throws IOException
public void writeBytes(String str) throws IOException
public void writeChars(String str) throws IOException
public void writeUTF(String str) throws IOException

public void writeUnshared(Object obj) throws IOException
public void writeFields() throws IOException

public void defaultWriteObject() throws IOException
public void useProtocolVersion(int version) throws IOException
public ObjectOutputStream.PutField putFields() throws IOException

public void reset() throws IOException

protected void writeObjectOverride(Object obj) throws IOException  
protected void annotateClass(Class<?> cl) throws IOException  
protected void annotateProxyClass(Class<?> cl) throws IOException  
protected Object replaceObject(Object obj) throws IOException
protected boolean enableReplaceObject(boolean enable) throws SecurityException
protected void writeStreamHeader() throws IOException
protected void writeClassDescriptor(ObjectStreamClass desc) throws IOException
protected void drain() throws IOException

int getProtocolVersion()  
void writeTypeString(String str) throws IOException

// Methods Inherited from OutputStream

public void write(int val) throws IOException
public void write(byte[] buf) throws IOException
public void write(byte[] buf, int off, int len) throws IOException

public void flush() throws IOException
public void close() throws IOException
ObjectOutputStream​ Constructors
ObjectOutputStream​(OutputStream out)
Объекты должны быть сериализованы (serialized) перед записью в ObjectOutputStream. Эти объекты должны реализовывать (implement) интерфейс Serializable.

2. Example 1

Класс 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.objectoutputstream.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.
OK, прочитаем файл, только что написанный на предыдущем шаге, с помощью ObjectInputStream.
ReadEmployeeDataEx.java
package org.o7planning.objectoutputstream.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. Example 2

Большинство классов в Java Collection Framework реализуют интерфейс Serializable, такой как ArrayList, LinkedList, HashMap, LinkedHashMap, TreeMap, ... поэтому их объекты доступны для записи в ObjectOutputStream.
Например, запишем в файл объект ArrayList.
Примечание: Все элементы ArrayList должны иметь тип Serializable..
WriteListEx1.java
package org.o7planning.objectoutputstream.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;
import java.util.List;

public class WriteListEx1 {

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

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        writeFile();

        readFile();
    }

    private static void writeFile() throws IOException {
        ArrayList<String> flowers = new ArrayList<String>();

        flowers.add("Tulip");
        flowers.add("Daffodil");
        flowers.add("Poppy");
        flowers.add("Sunflower");
        flowers.add("Bluebell");

        File file = new File(file_path);
        file.getParentFile().mkdirs();

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

        // Write a String
        oos.writeUTF("A list of flowers");
        // Write an Object
        oos.writeObject(flowers);
        oos.close();
    }
    
    @SuppressWarnings("unchecked")
    private static void readFile() 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 an Object
        List<String> flowers = (List<String>) ois.readObject();

        System.out.println(info);
        System.out.println();
        for (String s : flowers) {
            System.out.println(s);
        }
        ois.close();
    }
}
Output:
A list of flowers

Tulip
Daffodil
Poppy
Sunflower
Bluebell

4. writeFields()

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

import java.io.IOException;
import java.io.ObjectOutputStream;

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 writeObject(ObjectOutputStream out) throws IOException {

        ObjectOutputStream.PutField fields = out.putFields();
        // Write this object with custom fields

        fields.put("sound", this.sound < 20 ? 20 : this.sound);
        fields.put("bightness", this.bightness < 30 ? 30 : this.bightness);
        fields.put("difficultyLevel", this.difficultyLevel);
        
        // Do not write "userNote".
        // fields.put("userNote", this.userNote);

        out.writeFields();
    }
}
ObjectOutputStream_writeFields.java
package org.o7planning.objectoutputstream.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 ObjectOutputStream_writeFields {

    // 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, "Hard", "Try game again!");

        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: 20
bightness: 80
difficultyLevel: Hard
userNote: null
См. подробнее о методе ObjectInputStream.readFields():

5. writeUnshared​(Object)

Метод writeUnshared(Object) работает аналогично методу writeObject(Object), но отличается в следующей ситуации:
Предположим, вы хотите дважды записать объект "X" в ObjectOutputStream, что произойдет?
  1. objectOutputStream.writeObject(X);
  2. objectOutputStream.writeObject(X);
  1. Объект X будет сериализован (serialize) для получения результата Y, а затем запишет Y в цель.
  2. Написать ссылку Y на цель.
  1. objectOutputStream.writeUnshared(X);
  2. objectOutputStream.writeUnshared(X);
  1. Объект X будет сериализован (serialize) для получения результата Y, а затем запишет Y в цель.
  2. Объект X будет сериализован (serialize) для получения результата Y, а затем запишет Y в цель.
Например, используем метод writeObject для записи объекта ArrayList дважды в фай. И используем метод writeUnshared для записи объекта ArrayList дважды в другой файл. Второй файл будет иметь больший размер.
ObjectOutputStream_writeUnshared​.java
package org.o7planning.objectoutputstream.ex;

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

public class ObjectOutputStream_writeUnshared​ {

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

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        writeObjectTest();
        
        writeUnsharedTest();
    }
    
    private static void writeObjectTest() throws IOException  {
        File file = new File(file_path1);
        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.writeObject(list); // Write the first time
        oos.writeObject(list); // Write the second time
        oos.close();
    }

    private static void writeUnsharedTest() throws IOException  {
        File file = new File(file_path2);
        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();
    }
}
Output:

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

Show More