流
流:内存与储存设备之间传输数据的通道
输入流:将存储设备
中的内容读入到内存
中
输出流:将内存
中的内容写入到存储设备
中
字节流:以字节
为单位,可以读写所有数据
字符流:以字符
为单位,可以读写文本数据
节点流:具有实际传输数据的读写功能
过滤流:在节点流的基础之上增强功能
字节流
字节流基类
InputStream
字节流输入基类,抽象类是表示字节输入流的所有类的超类.// 从输入流中读取数据的下一个字节 abstract int read() // 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b中 int read(byte[] b) // 将输入流中最多 len 个数据字节读入 byte 数组 int read(byte[] b, int off, int len) // 跳过和丢弃此输入流中数据的 n个字节 long skip(long n) // 关闭此输入流并释放与该流关联的所有系统资源
OutputStream
字节输出流基类,抽象类是表示输出字节流的所有类的超类.// 将 b.length 个字节从指定的 byte 数组写入此输出流 void write(byte[] b) // 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流 void write(byte[] b, int off, int len) // 将指定的字节写入此输出流 abstract void write(int b) // 关闭此输出流并释放与此流有关的所有系统资源 void close() // 刷新此输出流并强制写出所有缓冲的输出字节 void flush()
字节文件操作流
FileInputStream
// 构造方法
// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定
FileInputStream(File file)
// 通过打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径name指定
FileInputStream(String name)
//基本使用
FileInputStream fis = new FileInputStream("C:\\Users\\1\\Documents\\Test.txt");
//单个字节读取
int data = 0;
while ((data = fis.read()) != -1) {
System.out.println((char)data);
}
//多个字节读取
byte[] buf = new byte[1024];
int count = 0;
while ((count = fis.read(buf)) != -1) {
/**
* 参数1为要显示的数组,这里是buf
* 参数2为代表数组从什么地方开始显示,这里为下标0的地方开始
* 参数3为显示几个元素,这里显示count个元素
*/
System.out.println(new String(buf, 0, count));
}
//一次读取一个字节数组,提高了操作效率,IO流使用完毕一定要关闭
fis.close();
System.out.println("close");
FileOutputStream
//构造方法
// 创建一个向指定File对象表示的文件中写入数据的文件输出流
FileOutputStream(File file)
// 创建一个向指定File对象表示的文件中写入数据的文件输出流
FileOutputStream(File file, boolean append)
// 创建一个向具有指定名称的文件中写入数据的输出文件流
FileOutputStream(String name)
// 创建一个向具有指定name的文件中写入数据的输出文件流
FileOutputStream(String name, boolean append)
//基本使用
OutputStream fos = new FileOutputStream(new File("test.txt"));
// 写出数据
fos.write(69);//这里插入的是对应的ascii表的对应编码
fos.write('a');
fos.write('b');
// 关闭IO流
fos.close();
// 内容追加写入
OutputStream fos = new FileOutputStream("test.txt", true);
// 输出换行符
fos.write("\r\n".getBytes());
// 输出追加内容
fos.write("hello".getBytes());
// 关闭IO流
fos.close();
//输出的目的地文件不存在,则会自动创建,不指定盘符的话,默认创建在项目目录下;输出换行符时一定要写\r\n不能只写\n,因为不同文本编辑器对换行符的识别存在差异性。
学完上边这些,下面实现一个复制操作
//文件字节输入流
FileInputStream fis = new FileInputStream("C:\\Users\\1\\Pictures\\o_201106013133212.jpg");
//文件字节输出流
FileOutputStream fos = new FileOutputStream("C:\\Users\\1\\Pictures\\cpoy.jpg");
//复制
byte[] buf = new byte[1024];
int count = 0;
while ((count = fis.read(buf)) != -1){
fos.write(buf,0,count);
}
//记得关闭
fis.close();
fos.close();
字节缓存流
BufferedInputStream
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("C:\\Users\\1\\Documents\\Test.txt"));
//读取
int data = 0;
while ((data = bis.read()) != -1){
System.out.print((char) data);
}
//读取
byte[] data = new byte[1024];
int count = 0;
while ((count = bis.read(data)) != -1) {
System.out.println(new String(data,0,count));
}
bis.close();
BufferedOutputStream
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("C:\\Users\\1\\Documents\\TestBuf.txt"));
for (int i = 0; i < 10; i++) {
bos.write("hello world\r\n".getBytes());//先写入缓冲区
bos.flush();//刷新到硬盘
}
bos.close();//这里执行close会执行flush
对象流
使用流传输对象的过程称之为序列化、反序列化.
需要序列化的对象必须实现Serializable
接口,才可以被序列化.
序列化
序列化是将对象状态转换为可保持或传输的格式的过程.与
序列化
相对的是反序列化
,它将流转换为对象,这两个过程结合起来,可以轻松的存储和传输数据.
ObjectOutputStream
OutputStream out = new FileOutputStream("C:\\Users\\1\\Documents\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(out);
//序列化(写入操作)
Student stu = new Student("saber",20);
oos.writeObject(stu);
//关闭
oos.close();
ObjectInputStream
InputStream in = new FileInputStream("C:\\Users\\1\\Documents\\stu.bin");
ObjectInputStream ois = new ObjectInputStream(in);
//反序列化(读取)
Student stu = (Student) ois.readObject();
Student stu2 = (Student) ois.readObject();//如果重复读取 会报EOFException的错误
System.out.println(stu);
ois.close();
使用注意
- 序列化类必须要实现
Serializable
接口 - 序列化类中的对象属性也必须实现
Serializable
接口 - 序列化版本ID,必须保证序列化的类和反序列化的类是同一个类
- 使用
transient
修饰的属性将不参与序列化 - 静态属性不会被序列化
- 序列化多个对象可以借助集合实现
字符流
常见字符编码
编码 | |
---|---|
ISO-8859-1 | 收录除ASCII外,还包括西欧、希腊语、泰语、阿拉伯语、希伯来语对应的文字符号 |
UTF-8 | 针对Unicode码表的可变长度字符编码 |
GB2312 | 简体中文 |
GBK | 简体中文、扩充 |
BIG5 | 中国台湾、繁体中文 |
注意:当编码方式和解码方式不一样时,会出现乱码
字符流基类
参考
文章1:https://blog.csdn.net/qq_33642117/article/details/52074796