IO流:
缓冲流: BufferedInputStream / BufferedOutputStream, BufferedReader / BufferedWriter
在基本流上增加缓冲区 char[] byte[], 提高读写效率
转换流: InputStreamReader / OutputStreamWriter
字节转字符: FileReader 读 char <- byte 硬盘
字符转字节: FileWriter 写 char -> byte 硬盘
序列化流: ObjectInputStream / ObjectOutputStream
序列化: 内存中的对象 写-> 硬盘上的文件中
反序列化: 内存中的对象 <-读 硬盘上的文件中
打印流: PrintStream
可以自动换行, 原样输出 System.out.println();
基本流: FileXxx
包装流:
包装流只是在基本流的外面增加了一些便捷的功能, 最终进行读写的还是基本流
但是包装流增强了基本流的功能
BufferedReader br = new BufferedReader(new FileReader());
字节缓冲流
|_ BufferedInputStream # 缓冲字节输入流
|_ BufferedOutputStream # 缓冲字节输出流
字符缓冲流
|_ BufferedReader # 缓冲字符输入流
|_ BufferedWriter # 缓冲字符输出流
java.io.BufferedOutputStream类: 缓冲字节输出流
// 构造方法
BufferedOutputStream(OutputStream out): 使用基本流创建一个缓冲字节输出流
BufferedOutputStream(OutputStream out, int size): 使用基本流创建一个缓冲字节输出流, 设置缓冲区大小
BufferedOutputStream使用步骤:
1.创建FileOutputStream对象, 构造方法中绑定要输出的目的地
2.创建BufferedOutputStream对象, 构造方法中传递FileOutputStream对象
3.使用BufferedOutputStream对象中的方法 write(), 把数据写入到内部缓冲区中
4.使用BufferedOutputStream对象中的方法 flush(), 把内部缓冲区中的数据,刷新到文件中
5.释放资源(会先调用flush方法刷新数据, 第4步可以省略)
FileOutputStream fos = new FileOutputStream("文件路径");
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.write("你好".getBytes());
// bos.flush(); // 可以省略
bos.close();
public class Test {
public static void main(String[] args) throws IOException {
// 1. 创建缓冲字节输出流对象, 内部传入基本流对象
// FileOutputStream fos = new FileOutputStream("testBufferedOutput1.txt");
// BufferedOutputStream bos = new BufferedOutputStream(fos);
// 以上代码可以合并为一行, 创建基本流使用匿名对象方式
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day10\\testBufferedOutput1.txt"));
// 2. 写数据
bos.write("我把数据写入到内存缓冲区中".getBytes());
// 刷新(可以省略, 直接使用close())
// bos.flush();
// 释放资源
bos.close();
}
}
public class Test {
public static void main(String[] args) throws IOException {
// 1. 创建缓冲字节输入流对象, 构造方法中传入基本流对象
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day10\\testBufferedOutput1.txt"));
// 读取数据方式1: 一次读一个字节
/*int by;
while ((by = bis.read()) != -1) {
System.out.println(by); // 这是int类型的byte数字
}*/
// 读取数据方式2: 一次读一个字节数组
int len;
byte[] bytes = new byte[1024];
while ((len = bis.read(bytes)) != -1) {
// 将读取到的字节转换为String, 并打印
System.out.print(new String(bytes, 0, len));
}
// 释放资源 只需要调用缓冲流的close方法即可, 该方法内部会自动将基本流对象关闭
bis.close();
}
}
public class Test {
public static void main(String[] args) throws IOException {
// 创建缓冲字符输出流对象, 构造方法内部传递基本流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("day10\\testBufferedWriter1.txt"));
// 循环10次写入内容和换行
for (int i = 0; i < 10; i++) {
// 写入内容
bw.write("传智播客");
// 写入换行符
bw.newLine();
}
// 刷新 (可以省略)
// bw.flush();
// 释放资源
bw.close();
}
}
public class Test {
public static void main(String[] args) throws IOException {
// 创建缓冲字符输入流对象, 构造方法中传递基本流对象
BufferedReader br = new BufferedReader(new FileReader("day10\\testBufferedWriter1.txt"));
// 循环读取
String line; // 定义String变量, 用于保存每次读到的一行字符串
while ((line = br.readLine()) != null) {
// 将读到的字符串打印出来, 因为字符串中不带换行符, 所以我们打印需要用println
System.out.println(line);
}
// 释放资源
br.close();
}
}
public class Test {
public static void main(String[] args) throws IOException {
// 创建集合, 用来装每行字符串
ArrayList<String> list = new ArrayList<>();
// 创建流对象
BufferedReader br = new BufferedReader(new FileReader("day10\\in.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("day10\\out.txt"));
// 循环按行读取
String line;
while ((line = br.readLine()) != null) {
// 添加到集合
list.add(line);
}
// 排序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// 先获取每个字符串的第一个字符char, 按照索引获取.
// char本身可以进行数学运算, 所以直接相减即可, 相当于按照 '1' '2' 的对应数值49 50 来相减
return o1.charAt(0) - o2.charAt(0); // 升序
}
});
// 遍历集合, 写到新文件中
for (String s : list) {
// 写字符串
bw.write(s);
// 写换行
bw.newLine();
}
// 释放资源
bw.close();
br.close();
}
}
java.io.OutputStreamWriter类: 输出转换流. 字符流通往字节流的桥梁
// 构造方法
OutputStreamWriter(OutputStream out): 使用默认编码表创建转换流
OutputStreamWriter(OutputStream out, String charsetName): 使用指定编码表创建转换流
// 使用默认UTF-8
OutputStreamWriter o = new OutputStreamWriter(new FileOutputStream("a.txt"));
o.write("dsfdsfdsaf")
// 使用指定的GBK
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "GBK");
osw.write("你") -> 查"GBK"码表 -> -1,-2 -> FileOutputStream -> a.txt文件
写数据: 字符流 --------------------------> 字节流
java.io.InputStreamReader类: 输入转换流. 字节流通往字符流的桥梁
// 构造方法
InputStreamReader(InputStream in): 使用默认编码表创建转换流
InputStreamReader(InputStream in, String charsetName): 使用指定编码表创建转换流
// 使用默认UTF-8
InputStreamReader r = new InputStreamReader(new FileInputStream("a.txt"));
// 使用指定的GBK
InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"), "GBK");
'你' <- 查"GBK"码表 <- isr.read() <- -1,-2 <- FileInputStream <- a.txt文件
读数据: 字符流 <---------- 字节流
public class Test {
public static void main(String[] args) throws IOException {
// 创建转换输入流对象, 指向GBK文件, 同时指定按照GBK来读取
InputStreamReader isr = new InputStreamReader(new FileInputStream("day10\\我是GBK.txt"), "GBK");
// 创建转换输出流对象, 路径填写utf8文件, 同时指定按照UTF-8来写
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day10\\我是UTF8文件.txt"), "UTF-8");
// 循环读写: 类似于文件复制, 一次读写一个字符
int ch;
while ((ch = isr.read()) != -1) {
// 读到一个写一个
osw.write(ch);
}
// 刷新缓冲区并释放资源
osw.close();
isr.close();
}
}
java.io.ObjectOutputStream类: 对象字节输出流
// 构造方法
ObjectOutputStream(OutputStream out)
// 特有成员方法
void writeObject(Object obj): 将对象写出
// 创建对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("student.txt"));
// 写对象
Student s = new Student("小美女", 18);
oos.writeObject(s);
// 释放资源
oos.close();
注意:
被读写的对象的类必须实现"java.io.Serializable"接口, 否则会抛出"NotSerializableException"
java.io.ObjectInputStream类: 对象字节输入流
// 构造方法
ObjectInputStream(InputStream in)
// 特有成员方法
Object readObject(): 读取对象
// 创建对象输入流
ObjectInputStream oos = new ObjectInputStream(new FileInputStream("student.txt"));
// 读对象
Object o = oos.readObject();
Student s = (Student)o;
System.out.println(s);
// 释放资源
oos.close();
public class Person {public class Person implements Serializable { // 实现序列化接口
private static final long serialVersionUID = 5608846017542335980L; // 定义序列版本号
private String name;
private int age;
public Person() {
}
public Person(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 "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 创建集合
ArrayList<Person> list = new ArrayList<>();
list.add(new Person("张三", 18));
list.add(new Person("李四", 19));
list.add(new Person("王五", 20));
// 创建对象输出流(序列化流)
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day10\\list.txt"));
// 写集合对象
oos.writeObject(list);
// 创建对象输入流(反序列化流)
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day10\\list.txt"));
// 读对象
Object o = ois.readObject();
// 将读取到的对象强转为集合
ArrayList<Person> list2 = (ArrayList<Person>)o;
// 遍历集合, 打印元素
for (Person person : list2) {
System.out.println(person);
}
}
}
PrintStream特点:
1. 只有输出流, 没有输入流
2. PrintStream不会抛出IOException
3. 有特殊方法 print(), println(), 可以输出任意类型的值, 原样输出
java.io.PrintStream类: 字节打印流
// 构造方法
PrintStream(File file): 创建字节打印流, 输出到一个文件
PrintStream(OutputStream out): 创建字节打印流, 输出到一个字节输出流
PrintStream(String fileName): 创建字节打印流, 输出到一个文件路径
注意事项:
如果用 write(97) 方法, 会查编码表 97 -> a
如果用 print(97), println(97), 则原样输出 97 int -> '9''7' -> byte -> 文件 97
System.out.println();
PrintStream out;
java.lang.System类:
// 静态方法
static void setOut(PrintStream out): 设置System.out的输出目的地为参数的打印流
// 体系结构:
字节流
|_ InputStream # 字节输入流
| |_ FileInputStream # 专门操作文件的字节输入流
| |_ BufferedInputStream # 带有缓冲区的字节输入流, 效率高
| |_ ObjectInputStream # 对象输入流
|
|_ OutputStream # 字节输出流
|_ FileOutputStream # 专门操作文件的字节输出流
|_ BufferedOutputStream # 带有缓冲区的字节输出流, 效率高
|_ ObjectOutputStream # 对象输出流
|_ PrintStream # 字节打印流
字符流
|_ Reader # 字符输入流
| |_ BufferedReader # 带有缓冲区的字符输入流, 效率高
| |_ InputStreamReader # 将字节流转换为字符流输入的转换输入流
| |_ FileReader # 专门操作文件的字符输入流
|
|_ Writer # 字符输出流
|_ BufferedWriter # 带有缓冲区的字符输出流, 效率高
|_ OutputStreamWriter # 将字符流转换为字节流输出的转换输出流
| |_ FileWriter # 专门操作文件的字符输出流
java.io.BufferedOutputStream类: 缓冲字节输出流
// 构造方法
BufferedOutputStream(OutputStream out): 使用基本流创建一个缓冲字节输出流
BufferedOutputStream(OutputStream out, int size): 使用基本流创建一个缓冲字节输出流, 设置缓冲区大小
java.io.BufferedInputStream类: 缓冲字节输入流
// 构造方法
BufferedInputStream(InputStream in): 使用基本流创建一个缓冲字节输入流
BufferedInputStream(InputStream in, int size): 使用基本流创建一个缓冲字节输入流, 设置缓冲区大小
java.io.BufferedWriter类:
// 构造方法
BufferedWriter(Writer out): 使用基本流创建一个缓冲字符输出流
BufferedWriter(Writer out, int size): 使用基本流创建一个缓冲字符输出流, 设置缓冲区大小
// 特有方法
void newLine(): 写入一个换行符, 换行符自动根据当前系统确定
java.io.BufferedReader类: 缓冲字符输入流
// 构造方法
BufferedReader(Reader in): 使用基本流创建一个缓冲字符输入流
BufferedReader(Reader in, int size): 使用基本流创建一个缓冲字符输入流, 设置缓冲区大小
// 特有方法
String readLine(): 一次读一行字符串, "不包含换行符". 读到文件末尾返回null
java.io.OutputStreamWriter类: 输出转换流. 字符流通往字节流的桥梁
// 构造方法
OutputStreamWriter(OutputStream out): 使用默认编码表创建转换流
OutputStreamWriter(OutputStream out, String charsetName): 使用指定编码表创建转换流
java.io.InputStreamReader类: 输入转换流. 字节流通往字符流的桥梁
// 构造方法
InputStreamReader(InputStream in): 使用默认编码表创建转换流
InputStreamReader(InputStream in, String charsetName): 使用指定编码表创建转换流
java.io.ObjectOutputStream类: 对象字节输出流
// 构造方法
ObjectOutputStream(OutputStream out)
// 特有成员方法
void writeObject(Object obj): 将对象写出
java.io.ObjectInputStream类: 对象字节输入流
// 构造方法
ObjectInputStream(InputStream in)
// 特有成员方法
Object readObject(): 读取对象
java.io.PrintStream类: 字节打印流
// 构造方法
PrintStream(File file): 创建字节打印流, 输出到一个文件
PrintStream(OutputStream out): 创建字节打印流, 输出到一个字节输出流
PrintStream(String fileName): 创建字节打印流, 输出到一个文件路径
java.lang.System类:
// 静态方法
static void setOut(PrintStream out): 设置System.out的输出目的地为参数的打印流
| 欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |