IO框架(1)
什么是流
概念:内存与存储设备之间传输数据的通道
这根水管就是一个流,用来为水库中的水传输到脸盆的一个通道
流的分类
按方向【重点】:
- 输入流:将<存储设备>中的内容读入到<内存>中。
- 输出流:将<内存>中的内容写入到<存储设备>中。
按单位:
- 字节流:以字节为单位,可以读写所有数据。
- 字符流:以字符为单位,只能读写文本数据。
按功能:
- 节点流:具有实际传输数据的读写功能。
- 过滤流:在节点流的基础之上增强功能。
字节流
字节流的父类(抽象类):
- InputStream:字节输入流
- public int read() {}
- public int read(byte[] b){}
- public int read (byte[] b, int off,int len){}
- OutputStream:字节输出流
- public void write(int n){}
- public void write (byte[] b){}
- public void write (byte[] b, int off, int len){}
文件字节流
FileInputStream:(是InputStream的继承)
public int read (byte[] b)//从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1。
FileOutputStream:(是OutputStream的继承)
public void write(byte[] b)//一次写多个字节,将b数组中所有字节,写入输出流。
package IO;
import java.io.FileInputStream;
//FieInputStream的使用
public class Demo01 {
public static void main(String[] args) throws Exception{
//1. 创建FileInputStream,并指定文件路径
FileInputStream file = new FileInputStream("d:\\aaa.txt");
//2.1单个字节 读取文件
//file.read();
//int data = 0;
//while ((data=file.read())!=-1){
// System.out.print((char) data+"\t");
//}
//2.2 多个字节 读取文件
byte[] a = new byte[3];
int b = 0;
while ((b=file.read(a))!=-1){
System.out.println(new String(a,0,b));
}
//3. 关闭
file.close();
}
}
package IO;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
//FileOutputStream的方法
public class Demo02 {
public static void main(String[] args) throws Exception{
//1. 创建文件字节输出流对象
FileOutputStream file = new FileOutputStream("d:\\bbb.txt",true);
//2. 写入文件
// file.write(97);
// file.write('b');
// file.write('c');
String string = "hello world";
file.write(string.getBytes(StandardCharsets.UTF_8));
//3. 关闭
file.close();
}
}
package IO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
//使用文件字节流实现文件的复制
public class Demo03 {
public static void main(String[] args) throws Exception{
//1. 创建流
//1.1 文件字节输入流
FileInputStream a = new FileInputStream("d:\\QQ图片20210414164333.png");
//1.2 文件字节输出流
FileOutputStream b = new FileOutputStream("d:\\00.png");
//2. 一边读,一边复制
byte[] buf =new byte[1024];
int count = 0;
while ((count=a.read(buf))!=-1){
b.write(buf,0,count);
}
//3. 关闭
a.close();
b.close();
}
}
字节缓冲流
缓冲流:BufferedInputStream/BufferedOutputStream
- 提高IO效率,减少访问磁盘的次数;
- 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close
package IO;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
//BufferedInputStream的使用
public class Demo04 {
public static void main(String[] args) throws Exception{
//1. 创建
FileInputStream a = new FileInputStream("d:\\aaa.txt");
BufferedInputStream b = new BufferedInputStream(a);
//2. 读取
// int data = 0;
// while ((data=b.read())!=-1){
// System.out.print((char)data+" ");
// }
byte[] c = new byte[1024];
int d = 0;
while ((d=b.read(c))!=-1){
System.out.println(new String(c,0,d));
}
//3. 关闭
b.close();//关闭缓冲字节流就会一起把字节流关闭
}
}
package IO;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
//使用字节缓冲流存入文件
//BufferedOutputStream的方法
public class Demo05 {
public static void main(String[] args) throws Exception{
//1. 创建
FileOutputStream a = new FileOutputStream("d:\\bbb.txt",true);
BufferedOutputStream b = new BufferedOutputStream(a);
//2. 写入文件
b.write("这是追加".getBytes(StandardCharsets.UTF_8));
b.flush();
//3. 关闭(内部调用flush方法)
b.close();
}
}
对象流
对象流:ObjectOutputStream/ObjectInputStream
- 增强了缓冲区功能
- 增强了读写8种基本数据类型和字符串功能
- 增强了读写对象的功能:
- readObject()从流中读取一个对象
- writeObject (0bject obj)向流中写入一个对象
使用流传输对象的过程叫做序列化和反序列化
package IO;
import java.io.Serializable;
public class Student implements Serializable{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
序列化操作
package IO;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
//ObjectOutputStream实现对象的序列号化
//要求:必须实现Serializable接口才能序列化
public class Demo06 {
public static void main(String[] args) throws Exception{
//1. 创建对象流
FileOutputStream b = new FileOutputStream("d:\\stu.bin");
ObjectOutputStream a = new ObjectOutputStream(b);
//2. 序列化(写入操作)
Student s1 = new Student("张三",18);
a.writeObject(s1);
//3. 关闭
a.close();
}
}
反序列化操作
package IO;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
//使用ObjectInputStream实现反序列化(读取重构成对象)
public class Demo07 {
public static void main(String[] args) throws Exception{
//1. 创建对象流
FileInputStream a = new FileInputStream("d:\\stu.bin");
ObjectInputStream b = new ObjectInputStream(a);
//2. 读取文件(反序列化)
Student c = (Student) b.readObject();
//3. 关闭
b.close();
System.out.println(c.toString());
}
}
注意事项:
- 序列化类必须要实现Serializable接口
- 序列化类中对象属性要求实现Serializable接口
- 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
- 使用transient(瞬间的)修饰属性,这个属性就不能序列化
- 静态属性不能被序列化
- 序列化多个对象
package IO;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
//ObjectOutputStream实现对象的序列号化
//要求:必须实现Serializable接口才能序列化
public class Demo06 {
public static void main(String[] args) throws Exception{
//1. 创建对象流
FileOutputStream b = new FileOutputStream("d:\\stu.bin");
ObjectOutputStream a = new ObjectOutputStream(b);
//2. 序列化(写入操作)
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",19);
Student s3 = new Student("王五",20);
ArrayList<Student> c = new ArrayList<>();
c.add(s1);
c.add(s2);
c.add(s3);
a.writeObject(c);
//3. 关闭
a.close();
}
}
package IO;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.ArrayList;
//使用ObjectInputStream实现反序列化(读取重构成对象)
public class Demo07 {
public static void main(String[] args) throws Exception{
//1. 创建对象流
FileInputStream a = new FileInputStream("d:\\stu.bin");
ObjectInputStream b = new ObjectInputStream(a);
//2. 读取文件(反序列化)
ArrayList<Student> s =(ArrayList<Student>) b.readObject();
//3. 关闭
b.close();
System.out.println(s.toString());
}
}