IO流知识点笔记
- 问题:代码中途异常(如
10/0),close()无法执行,导致IO 资源泄漏、Stream Closed 报错。 - JDK7 前:try-catch-finally
finally代码块无论是否报错必定执行,用来关闭流;- 流变量要定义在
try外面、初始值null,关闭前判空!=null,防止空指针。
- JDK7+:try-with-resources(推荐)
try()内写流对象,流实现AutoCloseable,代码结束自动关闭流,不用手动close()。
代码 1:try-finally 字节流复制
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyDemo1 { public static void main(String[] args) { // 1.流定义在try外,初始null,方便finally访问 FileInputStream is = null; FileOutputStream os = null; try { //2.创建输入流:绑定源文件 is = new FileInputStream("D:/resource/meinv.png"); //3.创建输出流:绑定目标文件 os = new FileOutputStream("E:/data/meinv.png"); //4.字节缓冲区,批量读写提升效率 byte[] buffer = new byte[1024]; int len;//保存每次读到的有效字节长度 //5.循环读写:读到文件末尾返回-1结束 while((len = is.read(buffer)) != -1){ os.write(buffer,0,len);//读多少写多少 } System.out.println(10/0);//模拟异常,测试finally生效 }catch(Exception e){ e.printStackTrace();//捕获异常打印信息 }finally { //finally必定执行,关闭输出流,先关输出再关输入 try { if(os != null) os.close();//判空,避免空指针 }catch (IOException e){e.printStackTrace();} try { if(is != null) is.close(); }catch (IOException e){e.printStackTrace();} } } }代码 2:try-with-resources 简化写法
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class CopyDemo2 { public static void main(String[] args) { //try()中声明流,程序结束自动关闭 try(FileInputStream is = new FileInputStream("D:/resource/meinv.png"); FileOutputStream os = new FileOutputStream("E:/data/meinv.png")){ byte[] buffer = new byte[1024]; int len; while((len = is.read(buffer)) != -1){ os.write(buffer,0,len); } System.out.println(10/0); }catch (Exception e){ e.printStackTrace(); } //无需手动close } }- 流定义在 try 内部→finally 拿不到变量,关不了资源;
- 不判空直接 close→
NullPointerException。
二、字符流(FileReader/FileWriter)
知识点笔记
- 适用范围:只读写纯文本文件,自动处理中文编码、不易乱码;图片 / 视频不能用。
- FileReader(字符输入):
read():读单个字符,末尾返回-1;read(char[] arr):读入字符数组,返回有效长度,末尾-1。
- FileWriter(字符输出):
- 构造第二个参数
true=追加写入,默认 false = 覆盖原文件; - 自带内存缓冲区:数据存内存,必须
flush()刷新 /close()关闭才落地到磁盘,否则文件无内容。
- 构造第二个参数
代码 3:FileReader 读取文本
import java.io.FileReader; import java.io.IOException; public class FileReaderTest { public static void main(String[] args) { try(FileReader fr = new FileReader("test.txt")){ char[] buf = new char[1024];//字符缓冲区 int len;//有效字符长度 while((len = fr.read(buf)) != -1){ //截取有效字符转字符串输出 System.out.print(new String(buf,0,len)); } }catch (IOException e){ e.printStackTrace(); } } }代码 4:FileWriter 写入文本
import java.io.FileWriter; import java.io.IOException; public class FileWriterTest { public static void main(String[] args) { //第二个参数true:追加写入 try(FileWriter fw = new FileWriter("test.txt",true)){ fw.write('中');//写入单个字符 fw.write("Java字符流");//直接写字符串(字符流独有) char[] arr = {'a','b','c'}; fw.write(arr);//写入字符数组 fw.flush();//手动刷新缓冲区,数据写入硬盘 }catch (IOException e){ e.printStackTrace(); } //close()自动执行flush,不写flush也可落地数据 } }易错:
- 忘记 flush/close→数据留在缓冲区,文件空白;
- 不带 true 参数,每次运行清空原有文件内容。
三、缓冲流(Buffered)
知识点笔记
- 原理:包装原始流,底层自带8192 (8KB) 缓冲区,减少磁盘 IO 次数,大幅提升读写速度。
- 四类缓冲流:
- 字节:
BufferedInputStream/BufferedOutputStream - 字符:
BufferedReader/BufferedWriter
- 字节:
- 字符缓冲独有:
BufferedReader.readLine():读取一行,读完返回null(不是 - 1);BufferedWriter.newLine():跨平台换行。
代码 5:字符缓冲流按行读写
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; public class BufferedTest { public static void main(String[] args) { //写入 try(BufferedWriter bw = new BufferedWriter(new FileWriter("buf.txt"))){ bw.write("第一行内容"); bw.newLine();//换行,兼容Windows/Linux bw.write("第二行内容"); }catch (IOException e){e.printStackTrace();} //读取 try(BufferedReader br = new BufferedReader(new FileReader("buf.txt"))){ String line;//存储每行字符串 while((line = br.readLine()) != null){//末尾是null,不能写-1 System.out.println(line); } }catch (IOException e){e.printStackTrace();} } }易错:
readLine()!= -1编译报错,字符串不能和数字对比;- 缓冲流不能直接传文件路径,必须包装原始流。
