Java 你往我来的 IO 流【第 07 篇】 Java 的 对象输出、输入流
对象输出流:ObjectOutputStream
对象输入流:ObjectInputStream
关于 Java 常用的 IO 流,整理了 07 篇文章,这是第 07 篇。如果是小白,或者一直没弄清楚 IO 流,请依次把这几篇文章过一遍。当然,高手就不用来我的博客浪费青春了。
小二,上代码:
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
// 如果没有序列化,在存取对象时会报非序列化异常:java.io.NotSerializableException
public class User implements Serializable
{
// 序列化:为了将对象保存到硬盘或数据库
// ObjeectInputStream 在读取时会先读取文件中的 serialVersionUID,如果与本地 class 文件的 serialVersionUID 不一致,则反序列失败
private static final long serialVersionUID = 1L;
private Integer id;
transient private String name; // transient 关键字修饰表示该变量不序列化,即不保存到硬盘文件
private Date birthday;
private char sex;
private BigDecimal pay;
@Override
public String toString()
{
return "用户编号:" + id + "\t用户名:" + name + "\t出生日期:" + birthday + "\t性别:" + sex + "\t工资:" + pay;
}
public User()
{
super();
}
public User(Integer id, String name, Date birthday, char sex, BigDecimal pay)
{
super();
this.id = id;
this.name = name;
this.birthday = birthday;
this.sex = sex;
this.pay = pay;
}
省略 get()、set() 方法
}
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/*
* 这个类的知识点(字符流)
* 1、使用 对象输出流 ObjectOutputStream 把对象序列化写入文件
* 2、使用 对象输入流 ObjectInputStream 把对象反序列化读到内存
*/
public class ObjectStream
{
public static void main(String[] args)
{
File file = new File("D:" + File.separator + "temp" + File.separator + "test.txt");
// 创建目录(这里如果不执行创建,那么必须保证 D 盘上有 temp 目录)
//file.getParentFile().mkdirs();
// 创建文件。这里不用手动创建也可以,因为下面在创建 FileOutputStream 实例时会自动创建
//file.createNewFile();
// 创建对象
User user01 = new User(101,"张三",new Date(),'男',new BigDecimal("9999.99"));
User user02 = new User(102,"李四",new Date(),'男',new BigDecimal("10999.99"));
// 创建对象集合
List<User> list = new ArrayList<User>();
list.add(user01);
list.add(user02);
// 调用对象输出流方法(把对象数据保存到硬盘文件)
saveObject(file,list);
// 调用对象输入流方法(把硬盘文件对象数据读取到内存)
readObject(file);
}
// 对象输出流(把对象数据保存到硬盘文件)
public static void saveObject(File file,List<?> list)
{
FileOutputStream fos = null; // 同上
ObjectOutputStream oos = null; // 为什么不放到 try 里面声明?如果把它放 try 里面声明,那么它的作用域仅限于 try,即只能在 try 里面使用它
try
{
fos = new FileOutputStream(file); // 创建 FileOutputStream 对象,因为 ObjectOutputStream 需要它作为参数
oos = new ObjectOutputStream(fos); // 创建 ObjectOutputStream 对象
oos.writeObject(list); // 将对象写入文件
// flush() 不是必须的,但一定要调用 close() 方法
// 如果 flush() 和 close() 方法都不调用,那么数据不能写入文件
oos.flush();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} finally // finally 作用:无论是否抛出异常,finally 代码块总是会被执行,这里用来释放资源
{
try
{
// 关闭流(如果不关闭流,那么相应的垃圾回收机制就不进行回收,导致垃圾越来越多,浪费资源)
if(oos != null)
{
oos.close();
}
if(fos != null)
{
fos.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
// 对象输入流(把硬盘文件对象数据读取到内存)
public static void readObject(File file)
{
FileInputStream fis = null; // 同上
ObjectInputStream ois = null; // 为什么不放到 try 里面声明?如果把它放 try 里面声明,那么它的作用域仅限于 try,即只能在 try 里面使用它
try
{
fis = new FileInputStream(file); // 创建 FileInputStream 对象,因为 ObjectInputStream 需要它作为参数
ois = new ObjectInputStream(fis); // 创建 ObjectInputStream 对象
List<User> list = (List<User>) ois.readObject(); // 读取硬盘文件对象并保存到 list 集合
for(User user : list) // 使用 for-each 将 list 集合中的对象依次循环并保存到 user 对象
{
System.out.println(user);
}
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} finally // finally 作用:无论是否抛出异常,finally 代码块总是会被执行,这里用来释放资源
{
try
{
// 关闭流(如果不关闭流,那么相应的垃圾回收机制就不进行回收,导致垃圾越来越多,浪费资源)
if(ois != null)
{
ois.close();
}
if(fis != null)
{
fis.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
}