day36
IO流
字符流继承图
字符流
继day35
应用场景:操作纯文本数据
注意:字符流 = 字节流+编译器
编译器:可以识别中文字符和非中文字符,非中文字符获取1个字节(一个字节=一个字符),编译器会根据编码格式获取中文字符对应的字节数(GBK获取两个字节,UTF-8获取三个字节)
abstract class Reader – 字符输入流的基类(抽象类)
abstract class Writer – 字符输出流的基类(抽象类)
class InputStreamReader extends Reader – 字符输入转换流
class OutputStreamWriter extends Writer – 字符输出转换流
特点:将字节流转换为字符流,字符转换流是字节流和字符流的桥梁
class FileReader extends InputStreamReader – 文件字符输入流
class FileWriter extends OutputStreamWriter – 文件字符输出流
class BufferedReader extends Reader – 带缓冲区的字符输入流
class BufferedWriter extends Writer – 带缓冲区的字符输出流
默认缓冲区:8192字符 – new char[8192]
文件字符输入、出流
利用 文件字符输出流 向文件写入数据
学习类比前面的学习思路,这里简化
public static void main(String[] args) throws IOException {//1.创建流对象//FileWriter fw = new FileWriter("io.txt");//1.创建流对象FileWriter fw = new FileWriter("io.txt", true);//2.写入数据fw.write("迪士尼");//3.关闭资源fw.close();}
利用 文件字符输入流 读取文件里的数据
public static void main(String[] args) throws IOException {//1.创建流对象FileReader fr = new FileReader("io.txt");//2.读取数据char[] cs = new char[1024];int len;while((len = fr.read(cs)) != -1){System.out.println(new String(cs, 0, len));}//3.关闭资源fr.close();}
拷贝文件
利用 文件字符输入、输出流
思路:读取源文件,写入目标文件
public class Copy {public static void main(String[] args) throws IOException {FileReader fr = new FileReader("小说.txt");FileWriter fw = new FileWriter("copy.txt");char[] cs = new char[1024];int len;while((len = fr.read(cs)) != -1){fw.write(cs, 0, len);}fr.close();fw.close();}
}
带缓冲区的字符输入、出流
利用 带缓冲区的字符输出流 向文件写入数据
public class Test01 {public static void main(String[] args) throws UnsupportedEncodingException, IOException {//1.创建流对象(文件字节输出流 -> 字符输出转换流 -> 带有缓冲区的字符输出流)//默认缓冲区大小:8192字符//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("io.txt"), "GBK"));//1.创建流对象(文件字节输出流 -> 字符输出转换流 -> 带有缓冲区的字符输出流)+ 末尾追加//默认缓冲区大小:8192字符//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("io.txt",true), "GBK"));//1.创建流对象(文件字符输出流 -> 带缓冲区的字符输出流)//默认缓冲区大小:8192字符//BufferedWriter bw = new BufferedWriter(new FileWriter("io.txt"));//1.创建流对象(文件字符输出流 -> 带缓冲区的字符输出流)+ 末尾追加//默认缓冲区大小:8192字符//BufferedWriter bw = new BufferedWriter(new FileWriter("io.txt",true));//1.创建流对象(文件字符输出流 -> 带缓冲区的字符输出流)+ 末尾追加 //自定义缓冲区大小:2048字符BufferedWriter bw = new BufferedWriter(new FileWriter("io.txt",true),2048);//2.写入数据bw.write("迪士尼");//3.关闭资源bw.close(); }
}
利用 带有缓冲区的字符输入流 读取文件里的数据
public class Test02 {public static void main(String[] args) throws UnsupportedEncodingException, IOException {//1.创建流对象(文件字节输入流 -> 字符输入转换流 -> 带有缓冲区的字符输入流)//默认缓冲区大小:8192字符//BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("io.txt"), "GBK"));//1.创建流对象(文件字节输入流 -> 字符输入转换流 -> 带有缓冲区的字符输入流)//默认缓冲区大小:8192字符//BufferedReader br = new BufferedReader(new FileReader("io.txt"));//1.创建流对象(文件字节输入流 -> 字符输入转换流 -> 带有缓冲区的字符输入流)//自定义缓冲区大小:2048字符BufferedReader br = new BufferedReader(new FileReader("io.txt"),2048);//2.读取数据char[] cs = new char[1024];int len;while((len = br.read(cs)) != -1){System.out.println(new String(cs, 0, len));}//3.关闭资源br.close();}
}
拷贝文件
利用 带有缓冲区的字符输入、输出流
思路:读取源文件,写入目标文件
方式1
public class Copy01 {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("小说.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"));char[] cs = new char[1024];int len;while((len = br.read(cs)) != -1){bw.write(cs, 0, len);}br.close();bw.close();}
}
方式2:行
public class Copy02 {public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new FileReader("小说.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("copy.txt"));// String readLine;
// while((readLine = br.readLine()) != null){
// bw.write(readLine);//写一行
// bw.newLine();//换行
// }boolean bool = false;String readLine;while((readLine = br.readLine()) != null){//第一行不换行if(bool){bw.newLine();//换行}bw.write(readLine);//写一行bool = true;}br.close();bw.close();}
}
各种流
对象流
class ObjectInputStream – 对象输入流
class ObjectOutputStream – 对象输出流
理解:
将程序中的对象写入到文件
并且从文件中读取出对象到程序里
ps:服务器宕机,文件里的对象没事,又可以拿出来
序列化(钝化):将程序里的对象写入到文件
反序列化(活化):将文件里的对象读取到程序中
注意:
- 如果对象想写入文件,对象所属的类就必须实现序列化接口(Serializable)
- Serializable序列化接口没有任何的属性和方法,这种接口称之为标记型接口
- 对象所属的类实现了序列化接口一定要添加序列化ID(serialVersionUID)
- 属性使用transient修饰,该属性不会随着对象而写入到文件中
利用对象输出流 向文件写入数据
public static void main(String[] args) throws FileNotFoundException, IOException {//1.创建流对象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));//2.写入数据oos.writeInt(100);//写入int值oos.writeDouble(123.123);//写入double值oos.writeUTF("迪士尼");//写入字符串oos.writeObject(new Date());//写入对象//3.关闭资源oos.close();}
利用对象输入流 读取文件里的数据
取出来能用,看不懂其中内容正常,读取和写入顺序一致,不然会报错
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {//1.创建流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));//2.读取数据(读取顺序必须和写入顺序一致)int readInt = ois.readInt();double readDouble = ois.readDouble();String str = ois.readUTF();Date date = (Date) ois.readObject();System.out.println(readInt);System.out.println(readDouble);System.out.println(str);System.out.println(date);//3.关闭资源ois.close(); }
利用对象输出流 向文件写入自定义对象
序列化id类似于版本,版本变化会导致读取不了的问题
public class User implements Serializable{//序列化接口private static final long serialVersionUID = 4907921883130742331L;//static final处理序列化idprivate String username;private transient String password;private String nickName;private String name;private String role;private double hp;private double mp;//无参、有参构造、get、set、toString方法【略】
}
public class Test03 {public static void main(String[] args) throws FileNotFoundException, IOException {//1.创建流对象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("io.txt"));//2.写入自定义对象oos.writeObject(new User("1445584980", "123123", "昨夜的酒", "小小", "无极剑圣", 10000, 10000));oos.writeObject(new User("1534534534", "111222", "撕裂的忧伤", "大大", "九尾妖狐", 8000, 9000));oos.writeObject(new User("5345356683", "123456", "落日黄昏", "奇男子", "逆羽", 9000, 8000));oos.writeObject(null);//不加会导致对象输入流读取对象报错//3.关闭资源oos.close();}
}
利用对象输入流 读取文件中的自定义对象
public class Test04 {public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {//1.创建流对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("io.txt"));//2.读取自定义对象User user;while((user = (User)ois.readObject()) != null){System.out.println(user);}//3.关闭资源ois.close();}
}
内存流
打印流
随机访问流
总结
1.FileReader、FileWriter
2.BufferedReader、BufferedWriter
注意:缓冲区大小-8192字符3.字符流继承图
4.ObjectInputStream、ObjectOutputStream
注意:
序列化接口
序列化、反序列的概念