IO流@功能流
IO流按照功能分为节点流和功能流,功能流具有加强性能的作用,都要包裹节点流使用;而功能流又分为缓冲流、基本数据类型流|Data流和Object 流| 对象流 | 引用数据类型流,接下来让我们来看看功能流。
功能流
缓冲流:
作用:提高读写效率
字节节点流:
FileInputStream 文件流 | ByteArrayInputStream 字节数组流
FileOutputStream | ByteArrayOutputStream
字节缓冲流 : 字节流功能流的一种
BufferedInputStream 字节输入缓冲流
BufferedOutputStream 字节输出缓冲流
无新增功能,可以发生多态
字符节点流
FileReader
FileWriter
字符缓冲流
BufferedReader
BufferedWriter
public class Class001_Buffered {
public static void main(String[] args) throws IOException {
//1.创建流
InputStream is = new BufferedInputStream(new FileInputStream("D://test.txt"));
OutputStream os = new BufferedOutputStream(new FileOutputStream("D://heihei.txt"));
//2.拷贝
byte[] car = new byte[1024];
int len = -1;
while((len=is.read(car))!=-1){
os.write(car,0,len);
}
//3.刷出
os.flush();
//4.关闭
os.close();
is.close();
}
}
基本数据类型流|Data流
作用:保留数据已经数据类型(基本数据类型+String)
DataInputStream
新增功能: readXxx()
DataOutputStream
新增功能: writeXxx()
注意:
读入与写出的顺序要保持一致
java.io.EOFException : 读入的文件不是源文件
public static void main(String[] args) throws IOException {
readFromFile("D:/d.txt");
}
//读入
public static void readFromFile(String path) throws IOException {
//1.创建流
DataInputStream is = new DataInputStream(new BufferedInputStream(new FileInputStream(path)));
//2.读入
int i = is.readInt();
boolean flag = is.readBoolean();
char ch = is.readChar();
String s = is.readUTF();
//3.处理数据
System.out.println(i);
System.out.println(flag);
System.out.println(ch);
System.out.println(s);
//4.关闭
is.close();
}
//写出
public static void writeToFile(String path) throws IOException {
//1.创建输出流
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(path)));
//2.准备数据
int i = 1;
boolean flag = false;
char ch = 'c';
String str = "哈哈";
//3.写出
out.writeInt(i);
out.writeBoolean(flag);
out.writeChar(ch);
out.writeUTF(str);
//4.刷出
out.flush();
//5.关闭
out.close();
}
Object 流
作用: 读写对象数据|引用数据类型的数据(包含基本数据类型)
ObjectInputStream 反序列化输入流
新增功能: readObject()
ObjectOutputStream 序列化输出流
新增功能: writeObject(Object obj)
序列化: 将对象数据转换一个可存储或者可传输的状态过程
先序列化后反序列化,不是所有的类型都能序列化 java.io.Serializable,不是所有的属性都需要序列化,静态的内容不会序列化,如果父类实现序列化,子类没有实现,可以序列化所有的成员, 如果子类实现序列化,父类实现,只能序列化子类成员 。
public class Class001_Object {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//writeToFile("D://e.txt");
readFile("D://e.txt");
}
//反序列化
public static void readFile(String path) throws IOException, ClassNotFoundException {
//1.输入流
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(path)));
//2.读入
User obj1 = (User) in.readObject();
int[] arr = (int[]) in.readObject();
//3.处理数据
System.out.println(obj1);
System.out.println(Arrays.toString(arr));
//4.关闭
in.close();
}
//序列化输出
public static void writeToFile(String path) throws IOException {
//1.输出流
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(path)));
//2.数据
User user = new User("zhangsan",18,"123");
int[] arr = {1,2,3,4};
//3.写出
out.writeObject(user);
out.writeObject(arr);
//4.刷出
out.flush();
//5.关闭
out.close();
//修饰user对象的成员,静态
user.username = "lisi";
user.password = "4321";
}
}
class User implements Serializable{
private static final long serialVersionUID = -5204947308809070324L;
public String username;
//transient 修饰的字段不会序列化
public transient int age;
public static String password;
//成员的修改: 新增的成员
public int vip;
public int id; //用户编号
public User() {
}
public User(String username, int age, String password) {
this.username = username;
this.age = age;
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
", password='" + password + '\'' +
'}';
}
}
通过序列号控制版本不一致问题:
1.实现Serializable接口的类型默认生成序列号,序列号会根据成员的修改做更新 serialVersionUID = -5204947308809070324
2.控制版本的统一问题: 控制类型修改之前与之后序列不变
3.通过工具生成序列号: 1.实现Serializable接口 2.setting设置 3.选中类名->alt+enter->生成序列号