IO
1 什么是流
- 概念:内存与存储设备之间传输数据的通道。
- 水借助管道传输;数据借助流传输。
2 流的分类
- 按方向【重点】:
- 输入流:将<存储设备>中的内容读入到<内存中>。
- 输出流:将<内存>中的内容写入到<存储设备中>。
-
按单位:
- 字节流:以字节为单位,可以读写所有数据。
- 字符流:以字符为单位,只能读写文本数据。
-
按功能:
- 节点流:具有实际传输数据的读写功能。
- 过滤流:在节点流的基础之上增强功能。
3 字节流抽象类
-
字节流的父类(抽象类):
-
InputStream: 字节输入流
- public int read(){}
- public int read(byte[] b){}
- public int read(byte[] b ,int off,int len){}
-
OutputStream:字节输出流
- public int write(){}
- public int write(byte[] b){}
- public int write(byte[] b ,int off,int len){}
4 文件字节流
- FileInputStream:
- public int read(byte[] b) //从流中读取多个字节,将读到内容存入b数组,返回实际读到的字节数;如果达到文件的尾部,则返回-1.
- FileOutputStream:
- public void write(byte[] b) //一次写多个字节,将b数组中所有字节,写入输出流。
package zhang.fileoutputstream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
/**
* @ClassName Demo02
* @Description TODO
* 字节流复制文件
* @Author Administrator
* @Date 2021/2/21 20:33
* @Version 1.0
**/
public class Demo02 {
public static void main(String[] args) throws Exception{
// 1 创建流
// 1.1文件字节输入流
FileInputStream fis =new FileInputStream("d:\\001.png");
// 1.2文件字节输出流
FileOutputStream fos = new FileOutputStream("d:\\002.png");
// 2 一边读,一边写
byte[] buf = new byte[1024];
int count = 0;
while ((count= fis.read(buf)) != -1) {
fos.write(buf, 0, count);
}
// 3 关闭
fis.close();
fos.close();
System.out.println("复制完毕");
}
}
5 字节缓冲流
- 缓冲流:BufferedInputStream/BufferOutputStream
- 提高IO效率,减少访问磁盘的次数
- 数据存储在缓冲区中,flush是将缓存区的内容写入文件中,也可以直接close。
6 对象流
-
对象流:ObjectOutputStream/ObjectInputStream
-
增强了缓冲区功能
-
增强了读写8种基本数据类型和字符串功能
-
增强了读写对象的功能:
- readObject() 从流中读取一个对象
- writeObject(Object obj) 向流中写入一个对象
-
使用流传输对象的过程称为序列化、反序列化
-
示例代码
package zhang.objectoutputstream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
* @ClassName Demo01
* @Description TODO
*
* 使用ObjectOutputStream实现对象的序列化
*
* 注意事项:
* (1)序列化类必须要实现Serializable接口
* (2)序列类中对象属性要求实现Serializable接口
* (3)序列化版本号ID,保证序列化的类和反序列化的类是同一个类
* (4)使用transient(瞬间的)修饰属性,这个属性不能序列化
* (5)静态属性不能序列化
* (6)序列化多个对象,可以借助集合实现
* @Author Administrator
* @Date 2021/2/22 13:09
* @Version 1.0
**/
public class Demo01 {
public static void main(String[] args) throws Exception {
// 1 创建对象流
FileOutputStream fos = new FileOutputStream("d:\\stu.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
// 2 序列化(写入操作)
Student xiaozhang = new Student("小张",12);
Student xiaoming =new Student("小明",13);
ArrayList<Student> arrayList = new ArrayList<>();
arrayList.add(xiaoming);
arrayList.add(xiaozhang);
oos.writeObject(arrayList);
// 3 关闭
oos.close();
System.out.println("序列化完毕");
}
}
package zhang.objectoutputstream;
import java.io.Serializable;
/**
* @ClassName Student
* @Description TODO
* @Author Administrator
* @Date 2021/2/22 13:07
* @Version 1.0
**/
public class Student implements Serializable {
// private static final long serialVersionUID = 6176793663535446505L;
/**
* serialVersionUID,序列化版本号ID
*/
private static final long serialVersionUID = 100L;
private String name;
private transient 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 zhang.objectinputstream;
import zhang.objectoutputstream.Student;
import java.io.FileInputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
/**
* @ClassName Demo01
* @Description TODO
* 使用ObjectInputStream实现反序列化(读取重构成对象)
*
* @Author Administrator
* @Date 2021/2/22 13:20
* @Version 1.0
**/
public class Demo01 {
public static void main(String[] args) throws Exception{
// 1 创建对象流
FileInputStream fis = new FileInputStream("d://stu.bin");
ObjectInputStream ois =new ObjectInputStream(fis);
// 2 读取文件(反序列化)
ArrayList<Student> s = (ArrayList<Student>) ois.readObject();
// 3 关闭
ois.close();
System.out.println("执行完毕");
System.out.println(s);
System.out.println(s.toString());
}
}
7 字符编码
- ISO-8859-1 收录除ASCII(1个字节)外,还包括西欧、希腊语、泰语、阿拉伯语、希望来语对应的文字符号
- UTF-8 针对Unicode码表的可变长度字符编码 (1、2、3个字节)
- GB2313 简体中文 (1、2 字节)
- GBK 简体中文(1、2 字节)
- BIG5 台湾,繁体中文
注意:当编码方式和解码方式不一致时,会出现乱码。
8 字符流
- 字符流的父类(抽象类):
- Reader: 字符输入流
- public int read(){}
- public int read(char[] c){}
- public int read(char[] b,int off, int len){}
- Writer:
- public void write(int n){}
- public void write(String str){}
- public void write(char[] c){}
- Reader: 字符输入流
9 文件字符流
- FileReader:
- public int read(char[] c) //从流中读取多个字符,将读到内容存入c数组,返回实际读到的字符数;如果达到文件的尾部,则返回-1;
- FileWriter:
- public void writer(String str) //一次写多个字符,将b数组中所有字符,写入输出流。
package zhang.filewriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
/**
* @ClassName Demo02
* @Description TODO
* 使用FileReader和FileWriter复制文本文件,不能复制图片或二进制文件
* 使用字节流复制任意文件
* @Author Administrator
* @Date 2021/2/23 14:14
* @Version 1.0
**/
public class Demo02 {
public static void main(String[] args)throws Exception {
// 1 创建 FileReader FileWriter
FileReader fr = new FileReader("d:\\a.txt");
FileWriter fw = new FileWriter("d:\\b.txt");
// 2 读写
int data = 0;
while ((data=fr.read()) != -1){
fw.write(data);
fw.flush();
}
// 3 关闭
System.out.println("复制完毕");
fr.close();
fw.close();
}
}
10 字符缓冲流
- 缓冲流:BufferedReader/BufferedWriter
- 高速读写
- 支持输入换行符。
- 可一次写一行、读一行。
11 打印流
- PrintWriter:
- 封装了print()/println()方法,支持写入后换行
- 支持数据原样打印
12 转换流
- 桥转换流:InputStreamReader/OutputStreamWriter
- 可将字节流转换为字符流。
- 可设置字符的编码方式。
13 File类
- 概念:代表物理盘符重点一个文件或者文件夹。
- 方法:
- createNewFile() //创建一个新文件
- mkdir() //创建一个新目录
- delete() //删除文件或空目录
- exists() //判断File对象所对象所代表的对象是否存在
- getAbsolutePath() //获取文件的绝对路径
- getName() //取得名字
- getParent() //获取文件、目录所在的目录
- isDirectory()// 是否是目录
- isFile() //是否是文件
- length() //获得文件的长度
- listFiles() //列出目录中的所有内容
- renameTo() //修改文件名为