尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

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

IO流(二)IO流中异常捕获方式、字符集和底层实现以及出现的问题的详细讲解,字符流的详细讲解,字节和字符流的综合练习
📅 发布时间:2026/6/22 1:17:08

(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(); } }

相关新闻

  • Nmap数据分析实战:从扫描到安全洞察的自动化方法
  • 2026玉溪防水补漏避坑指南:卫生间/厨房/阳台/屋顶/地下室漏水检测维修全攻略,正规施工+透明报价+口碑榜靠谱服务商推荐 - 安佳防水
  • 3分钟学会在Windows上安装APK文件:告别复杂模拟器的终极指南

最新新闻

  • 虚拟支持者在远程心理治疗中的技术架构与伦理边界探讨
  • 半导体设备展会参展参考,优选2026年业内主流半导体设备展会 - 品牌深度评测
  • 2026年重庆真正能学到职业技能的学校推荐 从实训到就业拆给你看 - 3158GEO
  • DPDSyn:任务导向的差分隐私数据合成技术原理与实践
  • STM32单片机生理监控心率脉搏TFT彩屏波形曲线65-3(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_文章底部可以扫码
  • TableSeq:基于图像到序列的端到端表格识别框架实战

日新闻

  • 2026速览惠州叛逆青少年学校前十大排名名单出炉 - 武汉中职最新信息发布
  • 2026上饶白蚁消杀哪家好?15年本土2大权威白蚁防治公司推荐(金盾虫控/青蚁卫士) - 我叫一
  • 天龙八部单机版终极数据管理工具:5个技巧快速掌握游戏数据编辑

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号