IO流-对象流

概述

对象流处理流的一种,用于将内存中的对象写入到数据源,并且能够将对象从数据源还原到内存。

序列化

概述

 将对象写入到数据源的过程称为对象的序列化。对象的序列化过程中,对象转化为与平台无关的二进制序列,通过对象流将二进制序列写入本地磁盘,或者将二进制序列传输到另一网络节点。
 实现对象序列化的流:ObjectOutputStream.

ObjectOutputStream

ObjectOutputStream处理流的一种。ObjectOutputStream类继承OutputStream抽象类,并且实现ObjectOutput接口和DataOutput接口。

构造器

public ObjectOutputStream(OutputStream out) throws IOException {}

常用方法

/* 刷新流 */
public void flush() throws IOException {}
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 writeBoolean(boolean val) throws IOException {}
public void writeInt(int val) throws IOException {}
public void writeFloat(float val) throws IOException {}
public void writeDouble(double val) throws IOException {}
public void writeChar(int val) throws IOException {}
public void writeByte(int val) throws IOException {}
public void writeLong(long val) throws IOException {}
public void writeShort(short val) throws IOException {}
public void writeChars(String str) throws IOException {}
public void writeBytes(String str) throws IOException {}
public void writeUTF(String str) throws IOException {}

public void close() throws IOException {}

/* 写入指定对象到流 */
public final void writeObject(Object obj) throws IOException {}

反序列化

概述

 将对象从数据源还原到内存的过程成为反序列化。实现对象反序列化的流:ObjectInputStream.

ObjectInputStream

ObjectInputStream处理流的一种。ObjectInputStream类继承InputStream抽象类,并且实现ObjectInput接口和DataInput接口。

构造器

public ObjectInputStream(InputStream in) throws IOException {}

常用方法

public void available() throws IOException {}
public int read() throws IOException {}
public int read(byte[] buf,int off,int len) throws IOException {}

public boolean readBoolean() throws IOException {}
public int readInt() throws IOException {}
public float readFloat() throws IOException {}
public double readDouble() throws IOException {}
public char readChar() throws IOException {}
public byte readByte() throws IOException {}
public long readLong() throws IOException {}
public short readShort() throws IOException {}
public String readUTF() throws IOException {}

public void close throws IOException {}

/* 从流读出一个对象 */
/* 注意:
   1.如果数据源中存在多种类型的对象序列,使用readObject()读取对象时注意类型匹配。
     一般要求实例引用按照writeObject()写入的顺序接收readObject()的返回。
   2.在数据源的末尾(没有更多对象序列时)使用readObject()会抛java.io.EOFException.  */
public final Object readObject() throws IOException,
                                        ClassNotFoundException {}

对象可序列化

概述

 不是所有类型的对象都能被序列化,只有可序列化的对象才能被序列化。使用对象流序列化不可序列化的对象时,将抛NotSerializableException.可使用Serializable接口使对象可序列化。

Serializable

Serializablejava.io包下的标记接口(空接口),实现Serializable接口可使对象可序列化。
 类实现Serializable接口时只需要显示指定Serializable接口中的静态常量:

static final long serialVersionUID = 42L;

serialVersionUID用于标记类的序列化版本。未显式指明时,系统将根据内部细节自动分配值。对于类的不同实例变量,serialVersionUID值可能分配不同。如果使用不同的实例变量接收反序列化的结果,系统会认为序列化版本不一致,抛InvalidCastException.
因此,必须显式指定SerialVersionUID的值(任意即可)

public class Person implements Serializable {
    /* 任意指定,无具体限制 */
    /* 没有引用价值的常量,推荐使用 private 修饰 */
    private static final long serialVersionUID = 5201314L;
}

对象可序列化的注意:

 ①使对象可序列化时,要求对象的所有属性均为可序列化的。Java中的基本数据类型和String都是可序列化的。

 ②使对象可序列化时,对象类中的静态成员不被序列化,因为静态成员归属于类,而并非归属于对象。

 ③对象中transient关键字修饰的成员不被序列化。如果要求对象中的某些成员不被序列化,可使用transient关键字修饰目标成员

对象流使用示例

Account.java

public class Account implements Serializable {
    
    //任意指定serialVersionUID的值
    private static final long serialVersionUID = 1003L;
    
    private String name;
    private long number;
    private String password;
    
    private static final String sp = File.separator;
    //账户存储文件
    private static final File savePath = new File("F:"+sp+"Desktop"+sp+"account.txt");
    
    public Account(String name,long number,String password) {
        this.name = name;
        this.number = number;
        this.password = password;
    }
    
    public void setName(String name) {this.name = name;}
    public String getName() {return name;} 
    
    public void setNumber(long number) {this.number = number;}
    public long getNumber() {return number;}
    
    public void setPassword(String password) {this.password = password;}
    public String getPassword() {return password;}
    
    public void save() {
        ObjectOutputStream oos = null;
        try{
            //覆盖原数据
            oos = new ObjectOutputStream(new FileOutputStream(savePath,false));
            oos.writeObject(this);
            oos.flush();
        } catch(IOException e){
            e.printStackTrace();
        } finally{
            if(oos != null){
                try{
                    oos.close();
                } catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
    
    //一台设备只有一个账户,使用静态方法获取
    public static Account getAccount() {
        ObjectInputStream ois = null;
        Account a = null;
        try{
            ois = new ObjectInputStream(new FileInputStream(savePath));
            a = (Account) ois.readObject();
        } catch(Exception e){
            e.printStackTrace();
        } finally{
            if(ois != null){
                try{
                    ois.close();
                } catch(IOException e){
                    e.printStackTrace();
                }
            } 
        }
        return a;
    }
    
    @Override
    public String toString(){
        String str = "--------------------\n"
                     + "name : " + name
                     + "\n--------------------\n"
                     + "number : " + number
                     + "\n--------------------\n"
                     + "password : " + password
                     + "\n--------------------\n";
        return str;
    }
}

Main.java

public class Main {
    public static void main(String[] args) {
        Account account = new Account("Tony",18372602180L,"123456789");
        account.save();
        System.out.println(Account.getAccount());
        //更改密码
        account.setPassword("abc.123");
        account.save();
        System.out.println(Account.getAccount());
    }
}

运行结果:

--------------------
name : Tony
--------------------
number : 18372602180
--------------------
password : 123456789
--------------------

--------------------
name : Tony
--------------------
number : 18372602180
--------------------
password : abc.123
--------------------
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值