注目記事

【Javaコード入門】ストリーム_⑤ObjectInputStream/ObjectOutputStreamクラス

オブジェクトの保存 – ObjectInputStream/ObjectOutputStreamクラス

ObjectInputStream(InputStream in)
ObjectOutputStream(OutputStream out)
 in:入力ストリーム
 out:出力ストリーム

Javaでは、Objectをシリアライズすることで、バイトストリームに出力するための手段を備えています。シリアライズとは、オブジェクトのような構造化データをファイル/ネットワーク経由でやり取りできるように、バイト配列に変換することを言います。シリアライズされたバイト配列を元のオブジェクトに戻すことをデシリアライズと言います。 そして、シリアライズ/デシリアライズのための機能を提供するのがObjectInputStream/ObjectOutputStreamクラスの役割です。以下に、主なメソッドをまとめます。

ObjectInputStream/ObjectOutputStreamクラスの主なメソッド
クラス メソッド 概要
ObjectInputStream int read([byte b [,int off, int len]]) 入力ストリームからバイト配列bに読み込み (offは開始位置、lenは読み込み長)
T readXxxxx() データ型Tで入力ストリームから読み込み
long skip(long n) 読み込みをnバイトだけスキップ
void close() ストリームを閉じる
ObjectOutputStream void write(byte b [,int off, int len]) バイト配列bの内容を出力ストリームに書き出し (offは開始位置、lenは読み込み長)
void writeXxxxx(T v) データ型Tで出力ストリームに書き込み
void close() ストリームを閉じる

以下は、オブジェクトPersonをファイルPerson.serに保存するためのサンプルです。また、Person.serを読み込み、その内容をオブジェクトとして復元しています。

StreamObject.java
  1. package com.example.mynavi.stream;
  2.  
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.ObjectInputStream;
  6. import java.io.ObjectOutputStream;
  7.  
  8. public class StreamObject {
  9.   public static void main(String[] args) {
  10.     var filename = "C:/data/Person.ser";
  11.     try(var out = new ObjectOutputStream(new FileOutputStream(filename));
  12.       var in = new ObjectInputStream(new FileInputStream(filename))) {
  13.       out.writeObject(new Person("山田太郎", 50));
  14.       var p = (Person) in.readObject();
  15.       p.showInfo(); // 結果:「山田太郎」50歳
  16.     } catch (Exception e) {
  17.       e.printStackTrace();
  18.     }
  19.   }
  20. }
Person.java
  1. package com.example.mynavi.stream;
  2.  
  3. import java.io.Serializable;
  4.  
  5. public class Person implements Serializable {
  6.  
  7.   private static final long serialVersionUID = -7053655917805742728L;
  8.   public String name;
  9.   public int age;
  10.   public transient boolean deleted;
  11.  
  12.   Person(String name, int age) {
  13.     this.name = name;
  14.     this.age = age;
  15.   }
  16.  
  17.   public void showInfo() {
  18.     System.out.println("「" + this.name + "」" + this.age + "歳");
  19.   }
  20. }

ObjectInputStream/ObjectOutputStreamクラスでシリアライズ/デシリアライズする場合、対象となるクラス(ここではPerson)は以下の条件を満たしている必要があります。

  • java.io.Serializableインターフェイス(※)を実装していること
  • インスタンスフィールドは、基本型、またはSerializable実装型であること
  • 基底クラスがシリアライズ不可の場合、基底クラスが引数のないpublicコンストラクターを持っていること

※Serializableインターフェイスはシリアライズが可能であることを示すためだけのマーカーインターフェイスで、実装すべきメソッドは持ちません。

また、定数searialVersionUIDは、クラスのバージョンを管理するための情報です。この定数が用意されている場合、シリアライズ/デシリアライズ側で異なるバージョンのクラスを利用している時に、例外を発生させることができます。
データの読み書きには、データ型に応じてreadXxxxx/writeXxxxxメソッドを利用できます(Xxxxxはデータ型に応じてBoolean、Byte、Char、Doubleなど)。一般的なオブジェクトを利用する場合には、readObject/writeObjectメソッドを利用します。

ストリーム_目次
ストリーム
FileInputStream/FileOutputStreamクラス
InputStreamReader/OutputStreamWriterクラス
BufferedReader/BufferedWriterクラス
ObjectInputStream/ObjectOutputStreamクラス
Fileクラス

監修

山田祥寛(有限会社 WINGSプロジェクト)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NEC にてシステム企画業務に携わるが、2003年 4 月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト(https://wings.msn.to/)」の代表でもある。主な著書に『改訂 3 版JavaScript 本格入門』(技術評論社)、「独習シリーズ(C#・Python・PHP・Ruby・JSP&サーブレットなど)」(翔泳社)、「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravel など)」(Amazon Kindle)など。売り上げの累計は100万部を超える。