缓冲流
缓冲流是对4个基本的 FileXxx 流的增强,所以也是4个流,按照数据类型分类:
- 字节缓冲流: BufferedInputStream , BufferedOutputStream
字符缓冲流: BufferedReader , BufferedWriter
缓冲流的基本原理:
在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率
字节缓冲流
字节输出缓冲流 BufferedOutputStream
- BufferedOutputStream 继承OutputStream,,操作时还是使用OutputStream的write方法
构造方法
BufferedInputStream 继承InputStream,操作还是使用InputStream的read方法
构造方法:
BufferedWriter 继承了Writer,可以使用父类Writer中的write方法
- 构造方法:
- BufferedWriter(Writer out) 参数要传入基本流,靠基本流来操作文件
特有方法:
BufferedReader 继承了Reader,可以使用父类Reader中的read方法
- 构造方法:
- BufferedReader(Reader in) 参数要传入基本流,靠基本流来操作文件
特有方法
读写一个字节,使用缓冲流,可以明显提高效率
- 读写一个字节数组,基本流和缓冲流差别不大
-
转换流
概述
-
输入转换流 InputStreamReader
InputStreamReader 继承 Reader
- 可以使用平台默认编码 或者 指定编码 读取字符
- InputStreamReader(InputStream in) 使用默认编码读取数据
InputStreamReader(InputStream in, String charsetName) 使用指定编码读取数据
输出转换流OutputStreamWriter
OutputStreamWriter 继承 Writer
- 可以使用平台默认编码 或者 指定编码 写出字符
- OutputStreamWriter(OutputStream out) 使用默认编码写数据
OutputStreamWriter(OutputStream out, String charsetName) 使用指定编码写数据 :::
对象流(序列化流)
对象操作流分为两类
ObjectOutputStream 对象输出流
-
对象操作流API
对象输出流
- ObjectOutputStream(OutputStream out) 对象输出流, 把对象以字节的形式写到本地文件
- public void writeObject(Object obj) 写一个对象到文件中
对象输入流
使用对象输出流将对象保存到文件时会出现NotSerializableException异常
- 解决办法:需要让类实现Serializable接口
- 用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类结构,读取数据会会出问题,会抛出InvalidClassException异常
- 解决办法:给对象所属的类加一个 serialVersionUID 属性
如果一个对象中的某个成员变量的值不想被序列化,那么给成员变量加transient关键字,该成员变量就不会被序列化到文件中 :::
打印流
字节打印流: PrintStream
继承自FileOutputStream,write()方法和 FileOutputStream 流一样,可以写出字节或者字节数组
特有的 println() 和 print() 方法,根据参数写出数据
字符打印流: PrintWriter
继承自Writer,write()方法和 Writer 流一样,可以写出字符或者字符数组或者字符串。
特有的 println() 和 print() 方法,根据参数写出数据
System.out.println()输出语句中的out对象,其实就是一个PrintStream类的对象
- System类内置了一个PrintStream对象,用于将数据快速打印到控制台
PrintStream 的API
构造器
- PrintStream(File file) 创建PrintStream, 指定打印的目的地
PrintStream(String fileName) 创建PrintStream, 指定打印的目的地
特有方法
print(Xxx x) 不换行打印,参数写什么,就输出什么
println(Xxx x) 换行打印,参数写什么,就输出什么
PrintWriter 和 PrintStream 用法几乎一样 只不过PrintStream是操作字节,PrintWriter是操作字符
属性集
:::tips
Properties 类表示属性集。他是一个特殊的集合,可以结合IO流操作
- Properties实现了Map接口,可以当做Map集合使用
Properties可以结合流进行数据读写,可以把集合中的数据保存到流中,也可以从流中来加载数据
Properties作为集合的特有方法
Object setProperty(String key, String value) 添加键和值,键和值都是String类型,键存在就覆盖值
- String getProperty(String key) 通过键获取值,如果键不存在,返回null
Set
stringPropertyNames() 获取所有的键 Properties和IO流结合的方法
void load(Reader reader) 使用字符输入流 加载 键值对 到Properties中
- void store(Writer writer, String comments) 使用字符输出流将Properties中的键值对 保存 到文件中
- void load(InputStream inStream) 使用字节输入流 加载 数据到Properties中
- void store(OutputStream out, String comments) 使用字节输出流将Properties中的数据保存到文件
:::
IO流异常处理
:::tipsJDK7增加 try-with-resource 语句来处理资源,该语句确保了每个资源在语句结束时关闭
- try(创建流对象,多个语句使用分号隔开) {
- 可能出现异常的代码;
- } catch(异常类名 变量名) {
- 异常的处理代码;
- }
自动关闭流,释放资源 :::
/*目标:学习字节缓冲流的使用1.字节缓冲输入流:BufferedInputStream2.特点:缓冲流以Buffered开头,用法和FileInputStream一样。缓冲流底层使用数组作为缓冲区,能提高读写的效率。3.构造方法:BufferedInputStream(InputStream in)*/public static void main(String[] args) throws Exception {//创建输入流对象BufferedInputStream input = new BufferedInputStream(new FileInputStream("Day11BufferedIO\\A\\a.txt"));byte[] arr = new byte[1024];int len;while ((len = input.read(arr)) != -1) {System.out.println(new String(arr, 0 ,len));}input.close();}
/*目标:学习字节缓冲流的使用1.字节缓冲输出流:BufferedOutputStream2.特点:缓冲流以Buffered开头,用法和FileOutputStream一样。缓冲流底层使用数组作为缓冲区,能提高读写的效率。3.构造方法:BufferedOutputStream(OutputStream out)*/public static void main(String[] args) throws Exception {//创建输出流对象BufferedOutputStream outPut = new BufferedOutputStream(new FileOutputStream("Day11BufferedIO\\A\\a.txt", true));//写入数据outPut.write("爪哇程序员".getBytes());outPut.close();}
/*目标:学习字符缓冲流的使用字符输入缓冲流:BufferedReader特点:继承自Reader,用法和FileReader一样。底层使用缓冲数组读取数据,效率高。构造方法:BufferedReader(Reader in)特有方法:String readLine() 读取一行数据,读取不到返回null*/public static void main(String[] args) throws Exception {BufferedReader reader = new BufferedReader(new FileReader("Day11BufferedIO\\A\\b.txt"));String line;//一次读取一行,到返回null结束while ((line = reader.readLine()) != null) {System.out.println(line);}reader.close();}
/*目标:学习字符缓冲流的使用字符输出缓冲流:BufferedWriter特点:继承自Reader,用法和FileWriter一样。底层使用缓冲数组读取数据,效率高。构造方法:BufferedWriter(Writer out)特有方法:void newLine() 写一个换行符,相当于写出"\r\n"注意:使用BufferedWriter写出数据后,记得调用flush或者close*/public static void main(String[] args) throws Exception {BufferedWriter writer = new BufferedWriter(new FileWriter("Day11BufferedIO\\A\\b.txt", true));writer.write("爪哇程序运行");writer.newLine();writer.write("爪哇程序运行");writer.close();}
//DEA中默认使用UTF-8编码,如果在IDEA中读取其他编码的文件,就容易乱码public static void main(String[] args) throws Exception {InputStreamReader reader = new InputStreamReader(new FileInputStream("Day11BufferedIO\\A\\gbk_file.txt"), "GBK");char[] arr = new char[1024];int len;while ((len = reader.read(arr)) != -1) {System.out.println(new String(arr, 0, len));}reader.close();}
/*练习文件的编码转换需求:读取GBK编码的文本文件gbk_file.txt,转换为UTF-8编码的文本文件utf8_file.txt。分析:使用GBK编码读取文件内容。使用UTF-8编码写字符数据到文件。循环读写*/public class DemoFileCode {public static void main(String[] args) throws Exception {InputStreamReader reader = new InputStreamReader(new FileInputStream("Day11BufferedIO\\A\\gbk_file.txt"), "GBK");OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("Day11BufferedIO\\A\\utf8_file.txt"), "UTF-8");char[] arr = new char[1024];int len;while ((len = reader.read(arr)) != -1) {writer.write(arr, 0, len);}reader.close();writer.close();}}
/*目标:使用对象输出流将内存中的对象写到文件中。ObjectOutputStream (对象输出流/序列化流)继承自OutputStream,可以将内存中的对象数据写出到文件中。1.构造方法: ObjectOutputStream(OutputStream out)2.序列化对象(将对象持久化保存): writeObject(Object obj)3.要求:对象所属的类要实现 Serializable接口4.transient关键字:被修饰的成员变量不会被序列化目标:使用对象输入流将文件中的对象读入程序中ObjectInputStream(对象输入流/反序列化流)把写到本地文件中的对象读到内存中。1.构造方法: ObjectInputStream(InputStream in)2.反序列化(将对象读回内存): Object readObject()*/public static void main(String[] args) throws Exception {Person person = new Person("张三", 23);//创建对象输出流ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream("Day11BufferedIO\\A\\c.txt"));//序列化对象(将对象持久化保存)output.writeObject(person);output.close();//创建对象输入流ObjectInputStream stream = new ObjectInputStream(new FileInputStream("Day11BufferedIO\\A\\c.txt"));//反序列对象(将对象读回内存)Object o = stream.readObject();System.out.println(o);stream.close();}//需要序列化对象,类要实现Serializable接口public class Person implements Serializable {//为当前类加一个唯一序列化标记private static final long serialVersionUID = 3725032426848681276L;private String name;//transient不让成员变量序列化private transient int age;//构造方法setgettoString}
/*目标:了解打印流的使用1.打印流分类:字节打印流: PrintStream字符打印流: PrintWriter2.PrintStream构造方法:PrintStream(String fileName) :根据字符串路径指定打印目的地。3.重要方法:print(任意类型数据) 打印数据,不换行println(任意类型数据) 打印数据,换行原样输出,参数写什么就打印什么说明:PrintWriter和PrintStream用法几乎一样。只不过PrintStream是操作字节,PrintWriter是操作字符。*/public static void main(String[] args) throws Exception {//打印流PrintStream stream = new PrintStream("Day11BufferedIO\\A\\d.txt");//保存数据到文件并且换行stream.println("123");stream.print("qwe");stream.close();}
/*目标:掌握Properties保存和加载文件的方式1.将Properties中的键值对数据保存到文件中:void store(Writer writer, String comments) :第一个参数为字符输出流,第二个参数为写到文件的注释。*/public static void main(String[] args) throws Exception {Properties p = new Properties();//添加键值对p.setProperty("张三", "23");p.setProperty("李四", "24");p.setProperty("王五", "25");p.store(new FileWriter("Day11BufferedIO\\A\\用户列表.txt"), "");}
/*2.加载文件数据到Properties集合中:void load (Reader reader) : 参数为字符输入流*/public static void main(String[] args) throws Exception {Properties p = new Properties();p.load(new FileReader("Day11BufferedIO\\A\\用户列表.txt"));Set<String> keys = p.stringPropertyNames();for (String key : keys) {String s = p.getProperty(key);System.out.println(key + " = " + s);}}
/*Properties作为Map集合的特有方法:Object setProperty(String key, String value) :添加键值对,键和值都是字符串类型。String getProperty(String key) :通过键获取值,获取不到返回nullstringPropertyNames() 获取所有的属性名,遍历属性名获取属性值*/public static void main(String[] args) {Properties p = new Properties();//setProperty 添加键值对,键和值都是字符串类型。p.setProperty("name","张三");p.setProperty("age","18");p.setProperty("address","广州");//getProperty(String key)String name = p.getProperty("name");System.out.println(name);//遍历 stringPropertyNames 获取所有的属性名Set<String> keys = p.stringPropertyNames();for (String key : keys) {String value = p.getProperty(key);System.out.println(key+","+value);}}
:::
