之前了解过java中的字符流和字节流来保存数据,但是使用字节流和字符流是不能保存对象的,java是面向对象语言 一切问题都当成是对象,保存一个对象我们可以使用数据流和对象流;
数据输入流:DataInputStream
对象输出流:ObjectInputStream
下面有一个类,保存其中的对象的方法如下:
public class Student {
String name;// 名字
byte age;// 年龄
float score;// 分数
int num;// 学号
String desc;// 个人简介
public Student(String name, byte age, float score, int num, String desc) {
this.name = name;
this.age = age;
this.score = score;
this.num = num;
this.desc = desc;
}
}
在使用对象数据流时,需要注意的是对字符串的处理(将字符串转化为字节来处理,在对象流中不需要),先获得字符串的长度-->根据长度创建字节数组-->写字节数组的长度-->写字符
//使用数据流来操作
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* 学生操作类
*
* @author
*
*/
public class StudentDB {
public static void main(String args[]) {
File file = new File("F:\\abc\\student.db");
// 字节数4+1+4+4+6
Student stu = new Student("张三", (byte) 20, 95.5F, 20120101, "youxiu");
saveStudent(file, stu);
System.out.println("保存成功!");
//创建一个读取对象的方法,在此接受并打印出来
Student stu2 = getStudent(file);
System.out.println(stu2.name);
System.out.println(stu2.age);
System.out.println(stu2.score);
System.out.println(stu2.num);
System.out.println(stu2.desc);
}
/**
* 将学生对象保存到指定的文件
*
* @param file
* 保存学生的文件
* @param stu
* 要保存的学生对象
*/
public static void saveStudent(File file, Student stu) {
try {
// 建立文件输出流
FileOutputStream fos = new FileOutputStream(file);
// 将输出流包装成基本数据类型输出流
DataOutputStream dos = new DataOutputStream(fos);
// 操作字符串的时候,还是采用字节来操作
// //获得名字的字节数组
byte[] names = stu.name.getBytes();
// 写名字字符串的字节长度
dos.writeInt(names.length);
// 写名字
dos.write(names);
// 写年龄
dos.writeByte(stu.age);
// 写分数
dos.writeFloat(stu.score);
// 学号
dos.writeInt(stu.num);
// 简介
byte[] descs = stu.desc.getBytes();
dos.writeInt(descs.length);
dos.write(descs);
// 强制输出
dos.flush();
// 关闭流
fos.close();
} catch (Exception ef) {
ef.printStackTrace();
}
}
/**
* 从文件中获取学生对象
*
* @param file
* 要获取对象的文件
* @return 返回获得的学生对象
*/
public static Student getStudent(File file) {
try {
// 建立文件输入流
FileInputStream fis = new FileInputStream(file);
// 包装成基本数据类型流
DataInputStream dis = new DataInputStream(fis);
// 读取名字的长度
int len = dis.readInt();
// 定义字节数组
byte[] names = new byte[len];
// 从流中读取字节填满数组
dis.read(names);
// 将字节数组转成字符串
String name = new String(names);
// 读取年龄
byte age = dis.readByte();
float score = dis.readFloat();
int num = dis.readInt();
// 简介
int len2 = dis.readInt();
byte[] descs = new byte[len2];
dis.read(descs);
String desc = new String(descs);
// 根据属性的值创建学生对象
Student stu = new Student(name, age, score, num, desc);
return stu;
} catch (Exception ef) {
ef.printStackTrace();
}
return null;
}
}
分析:数据流保存对象的难点在于对字符串的操作;上述的例子中:姓名和个人简介 是字符;串读取字符串的步骤:
先获取字符串长度-->根据获取长度创建字节数组--》从流中读取字节到数组中--》将字节组装换成字符串
将读到的字符串写出去的步骤:先获取数组中读到的字符串的字节数组-->将读取字节数组的长度写出去--》将字符串写出去;
//使用对象流来保存对象
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 学生操作类
*
* @author
*
*/
public class StudentDB {
public static void main(String args[]) {
File file = new File("F:\\abc\\student.db");
// 字节数4+1+4+4+6
Student stu = new Student("张三", (byte) 20, 95.5F, 20120101, "youxiu");
saveStudent(file, stu);
System.out.println("保存成功!");
//从文件中读取对象
Student stu2 = getStudent(file);
System.out.println(stu2.name);
System.out.println(stu2.age);
System.out.println(stu2.score);
System.out.println(stu2.num);
System.out.println(stu2.desc);
}
/**
* 将学生对象保存到指定的文件
*
* @param file
* 保存学生的文件
* @param stu
* 要保存的学生对象
*/
public static void saveStudent(File file, Student stu) {
try {
// 建立文件输出流
FileOutputStream fos = new FileOutputStream(file);
// 将输出流包装成对象输出流
ObjectOutputStream dos = new ObjectOutputStream(fos);
// 写名字
dos.writeObject(stu.name);
// 写年龄
dos.writeByte(stu.age);
// 写分数
dos.writeFloat(stu.score);
// 学号
dos.writeInt(stu.num);
// 简介
dos.writeObject(stu.desc);
// 强制输出
dos.flush();
// 关闭流
fos.close();
} catch (Exception ef) {
ef.printStackTrace();
}
}
/**
* 从文件中获取学生对象
*
* @param file
* 要获取对象的文件
* @return 返回获得的学生对象
*/
public static Student getStudent(File file) {
try {
// 建立文件输入流
FileInputStream fis = new FileInputStream(file);
// 包装成对象输入流
ObjectInputStream dis = new ObjectInputStream(fis);
// 读取名字
//对象中将字符串看做是一个Object来保存,使用向下转型
String name = (String)dis.readObject();
// 读取年龄
byte age = dis.readByte();
float score = dis.readFloat();
int num = dis.readInt();
// 简介
String desc = (String)dis.readObject();
// 根据属性的值创建学生对象
Student stu = new Student(name, age, score, num, desc);
return stu;
} catch (Exception ef) {
ef.printStackTrace();
}
return null;
}
}
分析:1,在使用对象流来保存对象,对字符串的保存时先将其强制转型为String String desc = (String)dis.readObject(); 写字符串只用将object写出去就可以了writeObject();
2,在读写的方法中都是将对象中的属性分别读取出来,不是整天的读取
//使用对象流来保存数据2
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* 学生操作类
*
* @author
*
*/
public class StudentDB2 {
public static void main(String args[]) {
File file = new File("F:\\abc\\student.db");
// 字节数4+1+4+4+6
Student stu = new Student("张三", (byte) 20, 95.5F, 20120101, "youxiu");
saveStudent(file, stu);
System.out.println("保存成功!");
// 从文件中读取对象
Student stu2 = getStudent(file);
System.out.println(stu2.name);
System.out.println(stu2.age);
System.out.println(stu2.score);
System.out.println(stu2.num);
System.out.println(stu2.desc);
}
/**
* 将学生对象保存到指定的文件
*
* @param file
* 保存学生的文件
* @param stu
* 要保存的学生对象
*/
public static void saveStudent(File file, Student stu) {
try {
// 建立文件输出流
FileOutputStream fos = new FileOutputStream(file);
// 将输出流包装成对象输出流
ObjectOutputStream dos = new ObjectOutputStream(fos);
//将对象写到输出流
dos.writeObject(stu);
// 强制输出
dos.flush();
// 关闭流
fos.close();
} catch (Exception ef) {
ef.printStackTrace();
}
}
/**
* 从文件中获取学生对象
*
* @param file
* 要获取对象的文件
* @return 返回获得的学生对象
*/
public static Student getStudent(File file) {
try {
// 建立文件输入流
FileInputStream fis = new FileInputStream(file);
// 包装成对象输入流
ObjectInputStream dis = new ObjectInputStream(fis);
//读取对象
Student stu = (Student) dis.readObject();
return stu;
} catch (Exception ef) {
ef.printStackTrace();
}
return null;
}
}
分析:上述代码是直接读取的对象;