1、字符流
字节流读取中文输出会存在什么问题?
- 会乱码。或者内存溢出。
读取中文输出,哪个流更合适,为什么?
- 字符流更合适,最小单位是按照单个字符读取的。
(1)文件字符输入流:FileReader
作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去
(2)文件字符输出流:FileWriter
作用:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件中去的流。
文件字符输出流(FileWriter)写数据出去的API:
流的关闭与刷新:
字节流、字符流的使用场景总结?
- 字节流适合做一切文件数据的拷贝(音视频,文本)
- 字节流不适合读取中文内容输出
- 字符流适合做文本文件的操作(读,写)
2、缓冲流
(1)概述
- 缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
- 作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能。
缓冲流种类
- 字节缓冲输入流: BufferedInputStream
- 字节缓冲输出流:BufferedOutputStream
- 字符缓冲输入流:BufferedReader
- 字符缓冲输出流:BufferedWriter
(2)字节缓冲流
字节缓冲流性能优化原理:
- 字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。
- 字节缓冲输出流自带了8KB缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了。
字节缓冲流
- 字节缓冲输入流:BufferedInputStream,提高字节输入流读取数据的性能。
- 字节缓冲输出流:BufferedOutputStream,提高字节输出流读取数据的性能。
示例:
import java.io.*; public class Test7 { public static void main(String[] args){ try { InputStream is=new FileInputStream("C:\\Users\\Eastward\\Pictures\\素材:时光清浅 水下嫣然\\低版本水下.jpg"); InputStream bis=new BufferedInputStream(is); OutputStream os=new FileOutputStream("C:\\Users\\Eastward\\Pictures\\素材1.jpg"); OutputStream bos=new BufferedOutputStream(os); byte[] buffer=new byte[1024]; int len; while((len=is.read(buffer))!=-1){ bos.write(buffer,0,len); } System.out.println("复制完成!"); } catch (Exception e) { e.printStackTrace(); } } }
(3)字符缓冲流
字符缓冲输入流:BufferedReader ,提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能
字符缓冲输出流:BufferedWriter,提高字符输出流写取数据的性能,除此之外多了换行功能
案例: 拷贝出师表到另一个文件,恢复顺序
需求:把《出师表》的文章顺序进行恢复到一个新文件中。
分析: ① 定义一个缓存字符输入流管道与源文件接通。
② 定义一个List集合存储读取的每行数据。
③ 定义一个循环按照行读取数据,存入到List集合中去。
④ 对List集合中的每行数据按照首字符编号升序排序。
⑤ 定义一个缓存字符输出管道与目标文件接通。
⑥ 遍历List集合中的每个元素,用缓冲输出管道写出并换行。
代码:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.util.*; public class Test8 { public static void main(String[] args){ try( BufferedReader br = new BufferedReader( new FileReader("C:\\Users\\Eastward\\Desktop\\Java\\假期练习2022.7\\Exercises12\\src\\test")); BufferedWriter bw = new BufferedWriter( new FileWriter("C:\\Users\\Eastward\\Desktop\\Java\\假期练习2022.7\\Exercises12\\src\\newTest")); ){ List<String> data=new ArrayList<>(); String line; while((line= br.readLine())!=null){ data.add(line); } System.out.println("原文件:"+data); //自定义排序规则 List<String> sizes=new ArrayList<>(); Collections.addAll(sizes,"1","2","3"); Collections.sort(data,new Comparator<String>(){ public int compare(String o1,String o2){ return sizes.indexOf(o1.substring(0,o1.indexOf("."))) -sizes.indexOf(o2.substring(0,o2.indexOf("."))); } }); System.out.println("排序后:"+data); for(String data1:data){ bw.write(data1); bw.newLine(); } }catch(Exception e){ e.printStackTrace(); } } }
示例:
原文件:[1.第一行, 3.第三行, 2.第二行]
排序后:[1.第一行, 2.第二行, 3.第三行]
3、转换流
(1)字符输入转换流
字符输入转换流:InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流。
字符输入转换流InputStreamReader作用:
可以解决字符流读取不同编码乱码的问题
public InputStreamReader(InputStream is,String charset): 可以指定编码把原始字节流转换成字符流,如此字符流中的字符不乱码。
(2)字符输出转换流
字符输入转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流。
字符输出转换流OutputStreamWriter的作用?
public OutputStreamWriter(OutputStream os,String charset)
可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码!
4、序列化对象
(1)对象序列化
使用到的流是对象字节输出流:ObjectOutputStream
作用:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化。
ObjectOutputStream序列化方法
(2)对象反序列化
使用到的流是对象字节输入流:ObjectInputStream
作用:以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化。
ObjectInputStream序列化方法
5、打印流
作用:打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指:PrintStream,PrintWriter两个类。
可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true。
(1)PrintStream、PrintWriter
PrintStream
PrintWriter
PrintStream和PrintWriter的区别
- 打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)
- PrintStream继承自字节输出流OutputStream,支持写字节数据的方法。
- PrintWriter继承自字符输出流Writer,支持写字符数据出去
(2)输出语句的重定向
属于打印流的一种应用,可以把输出语句的打印位置改到文件。
PrintStream ps = new PrintStream("文件地址") System.setOut(ps);
示例:
import java.io.PrintStream; import java.io.PrintWriter; /** * 目标:改变输出语句的位置到文件(输出语句重定向) */ public class PrintDemo2 { public static void main(String[] args) throws Exception { System.out.println("锦瑟无端五十弦"); System.out.println("一弦一柱思华年"); //改变输出语句的位置(重定向) PrintStream ps=new PrintStream("oi-app2/src/log.txt"); System.setOut(ps);//把系统打印流改成自己的打印流 System.out.println("庄生晓梦迷蝴蝶"); System.out.println("望帝春心托杜鹃"); } }
6、补充知识
(1)Properties
Properties属性集对象
- 其实就是一个Map集合,但是我们一般不会当集合使用,因为HashMap更好用。
Properties核心作用:
- Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
- 属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。
Properties的API:
- Properties和IO流结合的方法:
总结
Properties的作用?
- 可以存储Properties属性集的键值对数据到属性文件中去: void store(Writer writer, String comments)
- 可以加载属性文件中的数据到Properties对象中来: void load(Reader reader)
(2)IO框架
commons-io概述
- commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。
- commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils, IOUtils
FileUtils主要有如下方法:
导入commons-io-2.6.jar做开发
需求:使用commons-io简化io流读写
分析:① 在项目中创建一个文件夹:lib
② 将commons-io-2.6.jar文件复制到lib文件夹
③ 在jar文件上点右键,选择 Add as Library -> 点击OK
④ 在类中导包使用
目标:Commons-io包的使用介绍。
什么是Commons-io包? commons-io是apache开源基金组织提供的一组有关IO操作的类库, 可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类, 见下表: | 包 | 功能描述 | | ----------------------------------- | :------------------------------------------- | | org.apache.commons.io | 有关Streams、Readers、Writers、Files的工具类 | | org.apache.commons.io.input | 输入流相关的实现类,包含Reader和InputStream | | org.apache.commons.io.output | 输出流相关的实现类,包含Writer和OutputStream | | org.apache.commons.io.serialization | 序列化相关的类 步骤: 1. 下载commons-io相关jar包;http://commons.apache.org/proper/commons-io/ 2. 把commons-io-2.6.jar包复制到指定的Module的lib目录中 3. 将commons-io-2.6.jar加入到classpath中 小结: IOUtils和FileUtils可以方便的复制文件和文件夹!!
代码:
import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; public class CommonsIODemo01 { public static void main(String[] args) throws Exception { // 1.完成文件复制! // IOUtils.copy(new FileInputStream("C:\\Users\\zhao\\Pictures\\微信图片_20220429140831.jpg"),new FileOutputStream("D:\\Temp\\new.jpg")); // 2.完成文件复制到某个文件夹下! FileUtils.copyFileToDirectory(new File("C:\\Users\\zhao\\Pictures\\微信图片_20220429140831.jpg"),new File("D:/")); //3.完成文件夹复制到文件夹 FileUtils.copyDirectoryToDirectory(new File("D:/Temp/aaa"), new File("D:/Temp/ccc")); //删掉 FileUtils.deleteDirectory(new File("D:/Temp/ccc/aaa")); } }