JavaのIOアクション(3)-オブジェクトのシーケンス化、ObjectInputStream、ObjectOutputStreamクラス

4885 ワード

Javaは完全にオブジェクト向けの高度な言語であるため,プログラムを作成する際にデータはオブジェクトに格納されることが多い.メモリ内のオブジェクト全体をファイルに書き込み、適切なタイミングでファイルからメモリに復元する必要がある場合があります.このタスクはjava.io.ObjectInputStreamクラスとjava.io.ObjectOutputStreamクラスを使用して実行できます.
1、オブジェクトのシーケンス化(Serialize)
シーケンス化とは、オブジェクトの状態情報を格納または転送可能な形式に変換するプロセスである.シーケンス化中に、オブジェクトは現在のステータスを一時的または永続的なストレージ領域に書き込みます.その後、オブジェクトの状態をストレージ領域から読み出したり逆シーケンス化したりすることで、オブジェクトを再作成できます.
2、ObjectInputStreamクラスとObjectOutputStreamクラス
カスタムUserクラスのオブジェクトのようなオブジェクトをシーケンス化する場合は、Serializableインタフェースを実装する必要があります.Serializableインタフェースには抽象的な方法はありません.このインタフェースを実現するのは、コンパイラというオブジェクトがシーケンス化されることを通知するためだけです.同様の使い方にはCloneableインタフェースもあり、このインタフェースを実現することはコンパイラに通知する役割を果たすだけです.
オブジェクトのシーケンス化方法を示すために、まずUserクラスを設計します.
package cls;

import java.io.*;

public class User implements Serializable //   Serializable  ,                 
{
    //          
    private static final long serialVersionUID = 1L;
    
    private String name;
    private int num;
    
    public User(String name,int num)
    {
        this.name = name;
        this.num = num;
    }
    public String getName()
    {
        return name;
    }
    public int getNum()
    {
        return num;
    }
}

なお、seriaVersionUIDとは、シーケンス化可能なオブジェクトのバージョンを指す.このバージョンを指定していない場合、コンパイラはSerializableインタフェースを実装するクラスにseriaVersionUIDを自動的に生成します.自動生成であれば、一度にUserクラスを変更すると、自動生成されるseriaVersionUIDが異なります.ファイルからオブジェクトを読み込むとき、2つのオブジェクトのseriaVersionUIDが異なる場合、java.io.InvalidClassExceptionが放出されます.そのため、今後Userクラスを変更する必要がない場合は、この異常を防止するためにseriaVersionUIDを自分で指定したほうがいいです.
次に、ObjectInputStreamクラスとObjectOutputStreamクラスを使用してファイルに3つのUserオブジェクトを書き込み、1つのUserオブジェクトを追加し、最後にファイルからオブジェクトを読み込みます.
package cls;

import java.io.*;
import java.util.*;
import cls.User;

public class ObjectStreamDemo
{
    public static void main(String[] args)
    {
        User[] user = new User[]{new User("dogg",1),new User("catt",2),new User("pigg",3)};
        
        //         
        try
        {
            ObjectStreamDemo.writeObj(user,args[0]);
        }
        catch(Exception e)
        {
            System.out.println(e.toString());
        }
        
        //         
        try
        {
            //       
            User[] u = new User[]{new User("append1",4),new User("append2",5)};
            
            ObjectStreamDemo.appendObj(u,args[0]);
        }
        catch(Exception e)
        {
            System.out.println(e.toString());
        }
        //     
        try
        {
            List<User> list = ObjectStreamDemo.readObj(args[0]);
            
            //       
            Iterator<User> it = list.iterator();
            while(it.hasNext())
            {
                User temp = it.next();
                System.out.println(temp.getName() + "," + temp.getNum());
            }
        }
        catch(Exception e)
        {
            System.out.println(e.toString());
        }
    }
    
    static private void appendObj(Object[] objs,String fileName) throws Exception
    {
        File file = new File(fileName);
        
        //             
        FileOutputStream fis = new FileOutputStream(file,true);
        ObjectOutputStream oos = new ObjectOutputStream(fis)
        {
            //    writeStreamHeader()  ,   
            protected void writeStreamHeader(){};
        };
        
        //     
        for(Object o : objs)
        {
            oos.writeObject(o);
        }
        
        //    
        oos.close();
    }
    static private List<User> readObj(String fileName) throws Exception
    {
        File file = new File(fileName);
        
        //   List         
        ArrayList<User> list = new ArrayList<User>();
        
        //      
        FileInputStream fis = new FileInputStream(file);
        ObjectInputStream ois = new ObjectInputStream(fis);
        
        //        List   
        while(fis.available() > 0)
        {
            list.add((User)ois.readObject());
        }
        
        ois.close();
        return list; //   List
    }
    
    static private void writeObj(Object[] objs,String fileName) throws Exception
    {
        //               
        File file = new File(fileName);
        
        //      
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        
        //     
        for(Object o : objs)
        {
            oos.writeObject(o);
        }
        
        //    
        oos.close();
    }
}

注意、
既存のファイルにオブジェクトを追加する場合は、ObjectOutputStreamのwriteStreamHeader()メソッドを書き換え、空で実装する必要があります.なぜなら、ObjectOutputStreamは、データを書き込むときに特別なストリームヘッダ(Stream Header)を追加し、データを読み取るときにこのストリームヘッダをチェックするからです.したがって、ファイルにオブジェクトを追加すると、ObjectOutputStreamは再びファイルにストリームヘッダを書き込み、オブジェクトを読み込むときにStreamCorrupedException異常が発生します.