概况
I/O流主要分为二大类别:字符流和字节流。
字节流(基本流)
1、字节输入流 类名:FileInputStream 特点:读(对文件进行读取操作) 父类:InputStream
2、字节输出流 类名:FileOutputStream 特点:写 (对文件进行写入操作) 父类:OutputStream
字符流(基本流)
1、字符输入流 类名:FileReader 特点:读(对文件进行读取操作) 父类:InputStreamReader
2、字符输出流 类名:FileWriter 特点:写 (对文件进行写入操作) 父类:OutputStreamWriter
缓冲流
字节缓冲流
1、缓冲字节输入流 类名:BufferedInputStream 特点:读(对文件进行读取操作) 父类:FilterInputStream
2、缓冲字节输出流 类名:BufferedOutputStream 特点:写 (对文件进行写入操作) 父类:FilterOutputStream
字符缓冲流
1、缓冲字符输入流 类名:BufferedReader 特点:读(对文件进行读取操作) 父类:Reader (基本输入流多了readLine()
一次读取一行方法)
2、缓冲字符输出流 类名:BufferedWriter 特点:写 (对文件进行写入操作) 父类:Writer (比基本输出流多了newLine()
换行方法)
转换流
1、InputStreamReader 特点:读 (对文件进行读取操作) 输入流 父类:Reader
2、OutputStreamWriter 特点:写 (对文件进行写入操作) 输出流 父类:Writer
打印流
1、PrintStream 特点:写 (对文件进行写入操作) 底层:基本字节流
2、PrintWriter 特点:写 (对文件进行写入操作) 底层:基本字符流
基本字节流和基本字符流的区别:
1、字节流可以读写任何文件 字符流只能读取普通文件
2、读写文本文件尽量使用字符流 这要比字节流效率高
3、读写媒体文件用字节流
4、基本字节流没有缓冲区
5、基本字符流有缓冲区 默认大小为8k (不能指定缓冲区大小)
6、字节流是一个一个字节读 效率比较低 虽然可以读取各种各样的文件但是 最适用于读取媒体文件
7、字符流是一个一个字符读 效率比较高
缓冲流和基本流的区别:
1、缓冲流效率要高于基本流
2、缓冲字符流弥补了基本字符流不能设置缓冲区大小的缺口
3、缓冲字节流和基本字节流相比 建议使用基本字节流
4、缓冲字符流和基本字符流相比 建议使用缓冲字符流
转换流的作用
转换流的作用主要是解决在进行读写操作时出现的中文乱码 (java默认处理文件时是gbk 当将文本文件保存为utf-8的时候 进行读写操作就会出现中文乱码)
// 用转换流读写 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("a.txt"), "utf-8"); osw.write("中国"); osw.close(); InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"),"utf-8"); char[] cc = new char[10]; isr.read(cc); String ss = new String(cc); System.out.println(ss); isr.close();
API图
用法总结:
1、多媒体类 用字节流
读:基本字节输入流
写:基本字节输出流
2、文件文件 用字符流
读:建议用字符缓冲输入流
写:建议用字符缓冲输出流 如果写的数据多种多样的建议用打印流(PrintStream、PrintWriter)
3、比较明显意图的数据流
读写对象只能用对象流(ObjectInputStream、ObjectOutputStream)
如果在读写文件的过程中遇到中文乱码只能用转换流(InputStreamReader、OutputStreamWriter)
简单实例:
复制较小文件代码:
// 复制较小文件 // 先读后写 读的时候文件必须存在 不会自动创建 写的时候文件可以不存在会自动创建 File f = new File("D:\practice\backend\a.txt"); FileInputStream fis = new FileInputStream(f); byte[] b = new byte[(int)f.length()]; fis.read(b); fis.close(); // 写 FileOutputStream fos = new FileOutputStream("D:\practice\backend\b.txt");//不存在会自动创建 fos.write(b); fos.close();
复制较大文件代码:
// 读取复制大文件 // 一边读一边写 FileInputStream fis = new FileInputStream("D:\practice\backend\hello.mp4");//不存在不会自动创建 FileOutputStream fos = new FileOutputStream("D:\practice\backend\h.mp4");//不存在会自动创建 byte[] b = new byte[1024*1024];//每次读取1M while(true){ int len = fis.read(b); System.out.println(len); if(len == -1){ break;//当返回值是-1 证明文件已经读取完 终止循环 } fos.write(b, 0, len); } fis.close(); fos.close();
利用递归查找某个目录下的视频文件
public class Demo7 { public static void findAvi(String pathName){ File ff = new File(pathName); File[] fss = ff.listFiles(); for (File fa : fss) { if(fa.isFile()){//判断是否是文件 if(fa.getName().endsWith(".mp4")){//判断是否是视频文件 System.out.println(fa); } }else{ findAvi(fa.getPath()); } } } public static void main(String[] args) { // 递归查找某个目录下的视频文件 // E:迅雷下载 String ss = "E:\迅雷下载"; findAvi(ss);//静态方法只能访问静态方法 } }