IO流(二)IO流中异常捕获方式、字符集和底层实现以及出现的问题的详细讲解,字符流的详细讲解,字节和字符流的综合练习

📅 2026/6/22 1:12:14
IO流(二)IO流中异常捕获方式、字符集和底层实现以及出现的问题的详细讲解,字符流的详细讲解,字节和字符流的综合练习
3IO流中异常的捕获方式package ByteInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class ByteStreamDemo6 { public static void main(String[] args) throws FileNotFoundException { FileInputStream fis null; FileOutputStream fos null; /* 基本做法手动释放资源 */ try { fis new FileInputStream(E:\\java.File\\bbb\\屏幕截图 2026-04-14 215600.png); fos new FileOutputStream(opp-IO\\p.png); int len; byte[] bytes new byte[1024 * 1024 * 5]; while ((len fis.read(bytes)) ! -1) { fos.write(bytes, 0 ,len); } } catch (IOException e) { e.printStackTrace(); } finally { if (fos ! null) { try { fos.close(); }catch (IOException e) { e.printStackTrace(); } } if (fis ! null) { try { fis.close(); }catch (IOException e) { e.printStackTrace(); } } } /*JDK7IO流中的捕获异常写法 try后面的小括号中写创建对象的代码 注意只有实现了AutoCloseable接口的类才能在小括号中创建对象 而FileInputStream和FileOutputStream都实现了该接口类 AutoCloseable接口特点在特定情况下可以自动实现释放资源 try(){ }catch() { } */ try(FileInputStream fis new FileInputStream(E:\\java.File\\bbb\\屏幕截图 2026-04-14 215600.png); FileOutputStream fos new FileOutputStream(opp-IO\\p.png) ) { int len; byte[] bytes new byte[1024 * 1024 * 5]; while ((len fis.read(bytes)) ! -1) { fos.write(bytes, 0 ,len); } }catch (IOException e) { e.printStackTrace(); } /* JDK9以后 */ FileInputStream fis new FileInputStream(E:\\java.File\\bbb\\屏幕截图 2026-04-14 215600.png); FileOutputStream fos new FileOutputStream(opp-IO\\p.png); try(fis;fos) { int len; byte[] bytes new byte[1024 * 1024 * 5]; while ((len fis.read(bytes)) ! -1) { fos.write(bytes, 0 ,len); } }catch (IOException e) { e.printStackTrace(); } } }4字符集引入字节流读取文件时文件中不能出现中文否则读取出来的是乱码现象字符集分类ASCII 英文GBK 英文 中文Unicode 英文 中文—1、ASCII字符集ASCII字符集存储英文一个字节就足以。—2、GBK字符集GBK字符集Windows系统默认使用的就是GBK。系统显示ANSI计算机的存储规则英文GBK和ASSCII存储方式一样规则英文一个字节存储兼容ASCII,二进制前面补0.计算机的存储规则汉字GBK规则1一个汉字两个字节存储第一个字节叫高位字节第二个字节叫低位字节规则2高位字节二进制一定以1开头转成十进制之后是一个负数核心1GBK中一个英文字符一个字节二进制第一位是0核心2GBK中一个中文汉字两个字节二进制第一位是1—3、Unicode字符集Unicode字符集国际标准字符集它将世界各种语言的每个字符定义一个唯一的编码以满足跨语言跨平台的文本信息转换UTF-8是Unicode字符集的一种编码方式UTF-8编码规则用1~4个字节保存ASCII还是用一个字节而中文汉字用3个字节中文第一个字节是1注意一个英文占一个字节二进制第一位是 0转成十进制是正数一个中文占三个字节二进制第一位是 1第一个字节转成十进制是负数—4、乱码出现原因及解决方案为什么会出现乱码原因1读取数据时未读完整个汉字字节流一次读取一个字符原因2编码和解码时的方式不统一如何不产生乱码不要用字节流读取文本文件编码解码时使用同一个码表文件同一个编码方式—5、java中编码和解码的常用方法java中编码的方法String类中的方法public byte[] getBytes() 使用默认方式进行编码注str.getBytes()→ 无参默认 UTF-8IDEA 现在默认 UTF-81 个中文占 3 字节Public byte[] getBytes(String charsetName) 使用指定方式进行编码注str.getBytes(GBK)→ GBK 编码1 个中文占 2 字节java中解码的方法String类中的方法String(byte[] bytes) 使用默认方式进行解码注str.getBytes(GBK)→ GBK 编码1 个中文占 2 字节String(byte[] bytes, String charsetName) 使用指定方式进行解码注new String(bytes1,GBK):UTF-8 的字节强行用 GBK 规则解析 → 编码解码不一致 → 乱码public class ByteStreamDemo7 { public static void main(String[] args) throws IOException { //1、编码 String str ai你邮; byte[] bytes1 str.getBytes(); System.out.println(Arrays.toString(bytes1)); byte[] bytes2 str.getBytes(GBK); System.out.println(Arrays.toString(bytes2)); //2、解码 String str2 new String(bytes1); System.out.println(str2); String str3 new String(bytes1,GBK); System.out.println(str3); } }5字符流字符流字符流的底层其实就是字节流字符流字节流字符集特点输入流一次读一个字节遇到中文时一次读多个字节输出流底层会把数据按照指定的编码方式进行编码变成字节再写到文件中使用场景对纯文本文件进行读写操作—1、字符输入流FileReader1创建字符输入流对象Public FileReader(File file) 创建字符输入流关联本地文件Public FileReader(String pathname) 创建字符输入流关联本地文件细节1如果文件不存在就直接报错2读取数据Public int read() 读取数据读到末尾返回-1Public int read(char[] buffer) 读取多个数据读到末尾返回-1无参read方法细节按字节进行读取一次读一个字节遇到中文一次读取多个字节。读取后解码并转成十进制返回一个整数如果想看到中文汉字或者英文再进行强转就可以了。有参read方法细节把读取字节解码强转三步合并强转后的字符放到数组中细节2读到文件末尾了read方法返回-1.3释放资源Public int close 释放资源/关流package CharStream; import java.io.FileReader; import java.io.IOException; public class CharStreamDemo2 { public static void main(String[] args) throws IOException { FileReader fr new FileReader(opp-IO\\a.txt); int ch; while ((ch fr.read()) ! -1) { System.out.print((char)ch); } char[] chars new char[3]; /* read(chars)有参方法: 读取数据解码强转三步合并了把强转之后的字符放到数组当中 read()空参 : read 强制类型转换 */ int len; while ((len fr.read(chars)) ! -1) { //把数组中的数据变成字符串再进行打印 System.out.println(new String(chars,0,len)); } fr.close(); } }—2、字符输出流FileWriter构造方法Public FileWriter(File file) 创建字符输出流关联本地文件Public FileWriter(String pathname) 创建字符输出流关联本地文件Public FileWriter(File file, boolean append) 创建字符输出流关联本地文件续写Public FileWriter(String pathname, boolean append) 创建字符输出流关联本地文件续写FileWriter成员方法Void write(int c) 写出一个字符Void write(String str) 写出一个字符串Void write(String str, int off, int len) 写出一个字符串的一部分Void write(char[] cbuf) 写出一个字符数组Void write(char[] cbuf, int off, int len) 写出字符数组的一部分FileWriter书写细节1创建字符输出流对象细节1参数是字符串表示的路径或者File对象都是可以的细节2如果文件不存在会创建一个新的文件但是要保证父级路径是存在的细节3如果文件已经存在则会清空文件如果不想清空可以打开续写开关2写数据细节如果write方法的参数是整数但是实际上写到本地文件中的是整数在字符集上对应的字符3释放资源细节每次使用完流之后都要释放资源package CharStream; import java.io.FileWriter; import java.io.IOException; public class CharStreamDemo3 { public static void main(String[] args) throws IOException { FileWriter fw new FileWriter(opp-IO\\a.txt,true); //1、一次写一个字符如果遇到中文UTF-8中文3个字节GBK中文2个字节 fw.write(25105); fw.write(\r\n); //2、写一个字符串 fw.write(我在精神病院学斩神); fw.write(\r\n); //3、写出一个字符数组 char[] chars {o,k,,,我,要,修,仙}; fw.write(chars); fw.close(); } }6字节流和字符流的使用场景和综合练习字符流和字节流的使用场景字节流拷贝任意类型的文件字符流读取纯文本文件中的数据往纯文本文件中写出数据——1、拷贝一个文件夹package Text; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Text1 { public static void main(String[] args) throws IOException { //1、创建对象表示数据源 File src new File(E:\\java.File\\bbb); //2、创建对象表示目的地 File dest new File(E:\\java.File\\Text.opp\\aaa); copydir(src,dest); } /* 参数一数据源 参数二目的地 */ private static void copydir(File src, File dest) throws IOException { //如果dest文件不存在则创建一个新的 dest.mkdirs(); //递归 //1、进入数据源 File[] files src.listFiles(); //2、遍历数组 for (File file : files) { if(file.isFile()) { //3、判断文件拷贝 FileInputStream fis new FileInputStream(file);//拷贝到dest文件夹里面的文件中 // 所以父级路径是dest子级路径是dest里面的文件 FileOutputStream fos new FileOutputStream(new File(dest,file.getName())); byte[] bytes new byte[1024]; int len; while ((len fis.read(bytes)) ! -1) { fos.write(bytes, 0, len); } fos.close(); fis.close(); }else { //判断文件夹递归 copydir(file, new File(dest,file.getName())); } } } }——2、加密和解密文件package Text; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Text2 { public static void main(String[] args) throws IOException { /* ^ : 异或 两边相同false 两边不同true 如果异或两边是数字先把两边变成二进制然后逐位判断 100 ^ 10的结果是110 110 ^ 10的结果是100 所以可以利用上面的特性加密文件先后异或一个数字 */ //1、创建对象关联原始文件 FileInputStream fis new FileInputStream(opp-IO\\a.txt); //2、创建对象关联加密文件 FileOutputStream fos new FileOutputStream(opp-IO\\b.txt); int b; while ((b fis.read()) ! -1) { fos.write(b ^ 2); } /* 如果我此时想看加密文件则只需要把加密文件作为原始文件在创建一个关联文件进行解密即可 FileInputStream fis new FileInputStream(opp-IO\\b.txt); FileOutputStream fos new FileOutputStream(opp-IO\\c.txt); int b; while ((b fis.read()) ! -1) { fos.write(b ^ 2); } */ fos.close(); fis.close(); } }——3、修改文件中的数据package Text; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.function.Function; public class Text3 { public static void main(String[] args) throws IOException { /* 文本文件中数据 2-1-8-4-7-8 要求将文件中的数据进行排序变成以下的数据1-2-4-7-8-9 */ //1、获取数据 FileReader fr new FileReader(opp-IO\\a.txt); StringBuilder sb new StringBuilder(); int ch; while((ch fr.read()) ! -1) { sb.append((char)ch); } fr.close(); System.out.println(sb); //2、排序 // String str sb.toString(); // String[] arrStr str.split(-); // // ArrayListInteger list new ArrayList(); // for(String s : arrStr) { // int i Integer.parseInt(s); // list.add(i); // } // Collections.sort(list); // System.out.println(list); Integer[] arr Arrays.stream(sb.toString().split(-)) .map(new FunctionString, Integer() { Override public Integer apply(String s) { return Integer.parseInt(s); } }).sorted() .toArray(Integer[]::new); System.out.println(Arrays.toString(arr)); //3、写出 FileWriter fw new FileWriter(opp-IO\\a.txt); String s Arrays.toString(arr).replace(, ,-); String result s.substring(1,s.length()-1); fw.write(result); fw.close(); // FileWriter fw new FileWriter(opp-IO\\a.txt); // for (int i 0; i list.size(); i) { // if(ilist.size()-1) { // fw.write(list.get(i) ); // }else { // fw.write(list.get(i) -); // } // } // fw.close(); } }