当前位置: 首页 > news >正文

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

(3)IO流中异常的捕获方式

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(); } } } /*JDK7:IO流中的捕获异常写法 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. 规则1:一个汉字两个字节存储(第一个字节叫高位字节,第二个字节叫低位字节)

  2. 规则2:高位字节二进制一定以1开头,转成十进制之后是一个负数

核心1:GBK中,一个英文字符个字节,二进制第一位是0

核心2:GBK中,一个中文汉字个字节,二进制第一位是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-8(IDEA 现在默认 UTF-8),1 个中文占 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、字符输入流
FileReader

(1)创建字符输入流对象

Public FileReader(File file) 创建字符输入流关联本地文件

Public FileReader(String pathname) 创建字符输入流关联本地文件

细节1:如果文件不存在,就直接报错

(2)读取数据

Public int read() 读取数据,读到末尾返回-1

Public 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("-"); // // ArrayList<Integer> 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 Function<String, 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(i==list.size()-1) { // fw.write(list.get(i) + ""); // }else { // fw.write(list.get(i) + "-"); // } // } // fw.close(); } }
http://www.jsqmd.com/news/1058228/

相关文章:

  • 2026广东省“麦克奥迪斑羚杯”第七届大学生金相技能大赛——暨第十五届全国大学生金相技能大赛复赛(广东赛区) - 品牌发掘
  • 3分钟学会在Windows上安装APK文件:告别复杂模拟器的终极指南
  • MySQL慢查询日志:找到那些偷偷变慢的SQL
  • OBS虚拟摄像头终极指南:如何让任何软件都能使用你的直播画面?
  • 2026烟台防水补漏避坑指南:卫生间/厨房/阳台/屋顶/地下室漏水检测维修全攻略,正规施工+透明报价+口碑榜靠谱服务商推荐 - 安佳防水
  • 开源原神工具箱Snap Hutao:告别繁琐计算,专注游戏乐趣
  • Xournal++:免费开源手写笔记软件的终极解决方案
  • 如何永久保存微信聊天记录:免费高效的本地备份完整指南
  • VBA技术资料498_VBA_防止宏在只读模式下运行
  • 变革管理经典书籍推荐,这三本书做好组织变革必看
  • 380V工业吸尘器十大品牌排行,2025年实测推荐 - 工业清洁测评社
  • 基于CNN自编码器与MLP的象棋棋子动态价值预测模型构建
  • 鸿蒙给 Flutter 项目新增一个原生插件能力时,最小落地步骤是什么
  • 2026行业内质量好的线切割机床制造厂家怎么选 - 品牌排行榜
  • 3分钟完成漫画翻译:BallonTranslator深度学习辅助工具完全指南
  • 2026年现阶段斜板沉淀池生产厂家推荐哪家?江苏鑫邦达环保设备有限公司深度解析 - 品牌鉴赏官2026
  • MQX RTOS BSP移植实战:从手动搭建到脚本自动化全解析
  • WiFi指纹定位自适应半径近邻搜索:从原理到工程实现
  • 终极智能分层工具:LayerDivider让插画编辑效率提升500%
  • 2026潮州漏水检测维修本地口碑防水商家榜单:厨卫/阳台/屋面/地下室渗漏水维修,持证施工+明码实价,防水补漏公司TOP5推荐 - 即刻修防水
  • Ubuntu 24.04 apt-key废弃后安全添加第三方仓库的正确方法
  • i.MX31 WinCE LCD驱动移植实战:时序配置与BSP定制详解
  • B站会员购抢票神器:3步轻松实现自动化购票的终极指南
  • 如何让微信聊天记录成为你的数字资产:从数据提取到年度报告的完整指南
  • 大模型微调/RAG/Agent开发培训怎么选 2026年5家机构横向对比 - 互联网科技品牌测评
  • 2026年更新指南:聚焦成都知名的宴会桌椅优质厂家 - 品牌鉴赏官2026
  • QoderWake 与 Qoder 工具生态详解
  • 3D点云对抗防御:APC框架如何构建轻量级通用安全盾牌
  • D2DX宽屏补丁:让经典暗黑破坏神2在现代PC上重获新生的终极解决方案
  • 实用高效:3种方法解决数字音乐资产管理完整方案