【IO流系列】ConvertStream 转换流

转换流

    • 1. 概述
    • 2. 作用
    • 3. 字符编码和字符集
      • 3.1 字符编码
      • 3.2 字符集
    • 4. `InputStreamReader`字符转换输入流
      • 4.1 构造方法
      • 4.2 代码示例
    • 5. `OutputStreamWriter`字符转换输出流
      • 5.1 构造方法
      • 5.2 代码示例
    • 6. 练习
      • 6.1 练习1:转换文件编码
      • 6.2 练习2:读取文件数据
    • 7. 注意事项

文章中的部分照片来源于哔站黑马程序员阿伟老师处,仅用学习,无商用,侵权联系删除!

1. 概述

转换流是 Java 中用于在字节流和字符流之间进行转换的一种特殊流。

在处理数据时,有时候需要将字节流转换为字符流或字符流转换为字节流,这时就可以使用转换流来实现这种转换。转换流通常用于处理不同类型的数据,比如将字节流转换成字符流,或者将字符流转换成字节流。

在 Java 中,提供了两种主要的转换流:

  1. InputStreamReaderInputStreamReader 是用于将字节输入流转换为字符输入流的类。它接受一个字节输入流(如 FileInputStreamSocket.getInputStream())并根据指定的字符编码(如 UTF-8、GBK 等)将字节数据转换为字符数据。

  2. OutputStreamWriterOutputStreamWriter 是用于将字符输出流转换为字节输出流的类。它接受一个字节输出流(如 FileOutputStreamSocket.getOutputStream())并根据指定的字符编码将字符数据转换为字节数据。

在这里插入图片描述

2. 作用

  1. 字节流和字符流的转换:转换流允许将字节流转换为字符流,以便更方便地处理文本数据。通过InputStreamReader将字节输入流转换为字符输入流,通过OutputStreamWriter将字符输出流转换为字节输出流,使得在处理文本数据时更加方便。

  2. 字符编码转换:转换流提供了指定字符编码的功能,可以在转换流的构造方法中指定具体的字符编码,从而确保在字节和字符之间转换时使用指定的编码规则,避免因编码不一致导致的乱码等问题。

  3. 处理不同数据格式:转换流可以帮助处理来自外部数据源的字节数据,将其转换为字符数据进行处理,或者将处理完的字符数据转换为字节数据输出到外部数据源中,使得处理不同格式数据更加灵活。

在这里插入图片描述

3. 字符编码和字符集

3.1 字符编码

计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码

反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本符号。反之,按照A规则存储,再按照B规则解析,就会导致乱码现象。

编码:字符(能看懂的)–字节(看不懂的)

解码:字节(看不懂的)–>字符(能看懂的)

  • 字符编码Character Encoding : 就是一套自然语言的字符与二进制数之间的对应规则。

    编码表:生活中文字和计算机中二进制的对应规则

3.2 字符集

  • 字符集 Charset:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。

计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等。
在这里插入图片描述

可见,当指定了编码,它所对应的字符集自然就指定了,所以编码才是我们最终要关心的。

  • ASCII字符集
    • ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。
    • 基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。
  • ISO-8859-1字符集
    • 拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。
    • ISO-8859-1使用单字节编码,兼容ASCII编码。
  • GBxxx字符集
    • GB就是国标的意思,是为了显示中文而设计的一套字符集。
    • GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。
    • GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。
    • GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。
  • Unicode字符集
    • Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。
    • 它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。
    • UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:
      1. 128个US-ASCII字符,只需一个字节编码。
      2. 拉丁文等字符,需要二个字节编码。
      3. 大部分常用字(含中文),使用三个字节编码。
      4. 其他极少使用的Unicode辅助字符,使用四字节编码。

4. InputStreamReader字符转换输入流

4.1 构造方法

  • InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。

  • InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集的字符流。

    构造举例,代码如下:

    InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"));
    InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt") , "GBK");
    

4.2 代码示例

  • 代码示例
    需求:手动创建一个GBK的文件,把文件中的中文读取到内存中,不能出现乱码

    GBK文件: D:\JavaCode\code\codeText01\src\text\IOStream\ConvertStream\ConvertStream01\GBK01.txt

    package text.IOStream.ConvertStream.ConvertStream01;
    
    import java.io.FileInputStream;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.nio.charset.Charset;
    
    /*转换文件编码
    
    需求:手动创建一个GBK的文件,把文件中的中文读取到内存中,不能出现乱码
      GBK文件:  D:\JavaCode\code\codeText01\src\text\IOStream\ConvertStream\ConvertStream01\GBK01.txt
    
     */
    public class ConvertStream01 {
        public static void main(String[] args) throws IOException {
            //原始方法(了解就行)
            System.out.println("原始方法:");
            method1();
    
            System.out.println();
    
            //JDK11以后得方法(需要掌握)
            //在JDK11以后java在FileReader的构造方法中添加了InputStreamReader字符转换流的对象
            System.out.println("JDK11以后得方法:");
            method2();
        }
    
        //原始方法(了解就行)
        public static void method1() throws IOException {
            //创建转换输入流对象
            InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\JavaCode\\code\\codeText01\\src\\text\\IOStream\\ConvertStream\\ConvertStream01\\GBK01.txt"), "GBK");
            //读取数据
            int b;
            while ((b = isr.read()) != -1) {
                System.out.print((char) b);
            }
    
            //释放资源
            isr.close();
        }
    
        //JDK11以后得方法(需要掌握)
        public static void method2() throws IOException {
            //创建输入流对象
            FileReader fis = new FileReader("D:\\JavaCode\\code\\codeText01\\src\\text\\IOStream\\ConvertStream\\ConvertStream01\\GBK01.txt", Charset.forName("GBK"));
            //读取数据
            int b;
            while ((b = fis.read()) != -1) {
                System.out.print((char) b);
            }
    
            //释放资源
            fis.close();
        }
    }
    
    
    
  • 输出结果

    • GBK文件(因为idea默认是UTF-8,因此会出现乱码形象)
      在这里插入图片描述
    • 原始方法
      在这里插入图片描述
    • JDK11以后方法
      在这里插入图片描述

5. OutputStreamWriter字符转换输出流

5.1 构造方法

  • OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。

  • OutputStreamWriter(OutputStream in, String charsetName): 创建一个指定字符集的字符流。

    构造举例,代码如下:

    OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream("out.txt"));
    OutputStreamWriter isr2 = new OutputStreamWriter(new FileOutputStream("out.txt") , "GBK");
    

5.2 代码示例

  • 代码示例
    需求:把一段中文按照GBK的方式写到本地文件
    package text.IOStream.ConvertStream.ConvertStream02;
    
    import java.io.*;
    import java.nio.charset.Charset;
    
    /*转换文件编码
    
    需求:把一段中文按照GBK的方式写到本地文件
     */
    public class ConvertStream02 {
        public static void main(String[] args) throws IOException {
            //原始方法(了解就行)
            System.out.println("原始方法:");
            method1();
    
            System.out.println();
    
            //JDK11以后得方法(需要掌握)
            //在JDK11以后java在FileWriter的构造方法中添加了InputStreamWriter字符转换流的对象
            System.out.println("JDK11以后得方法:");
            method2();
        }
    
        //JDK11以后得方法(需要掌握)
        private static void method2() throws IOException {
            //创建对象
            FileWriter fw = new FileWriter("D:\\JavaCode\\code\\codeText01\\src\\text\\IOStream\\ConvertStream\\ConvertStream02\\a.txt", Charset.forName("GBK"));
            //输出数据
            String str = "星光闪烁,如同我们之间的誓言,\n" +
                    "余生余生,只愿与你相伴。";
            fw.write(str);
            //释放资源
            fw.close();
        }
    
        //原始方法(了解就行)
        private static void method1() throws IOException {
            //创建对象
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("D:\\JavaCode\\code\\codeText01\\src\\text\\IOStream\\ConvertStream\\ConvertStream02\\a.txt"), "GBK");
            //输出数据
            String str = "星光闪烁,如同我们之间的誓言,\n" +
                    "余生余生,只愿与你相伴。";
            osw.write(str);
            //释放资源
            osw.close();
        }
    
    }
    
    
  • 输出结果
    • ieda里展示的文件(因为idea默认是UTF-8,因此会出现乱码形象)
      在这里插入图片描述
    • 记事本中打开(记事本默认是GBK)
      在这里插入图片描述

6. 练习

6.1 练习1:转换文件编码

  • 需求:将本地文件中的GBK文件,转成UTF-8

    GBK文件:D:\JavaCode\code\codeText01\src\text\IOStream\ConvertStream\ConvertStream03\GBK01.txt
    UTF-8:D:\JavaCode\code\codeText01\src\text\IOStream\ConvertStream\ConvertStream03\UTF8

  • 代码示例
    package text.IOStream.ConvertStream.ConvertStream03;
    
    import java.io.FileInputStream;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.nio.charset.Charset;
    
    /*转换文件编码
    
    需求:将本地文件中的GBK文件,转成UTF-8
    GBK文件:D:\JavaCode\code\codeText01\src\text\IOStream\ConvertStream\ConvertStream03\GBK01.txt
    UTF-8:D:\JavaCode\code\codeText01\src\text\IOStream\ConvertStream\ConvertStream03\UTF8
     */
    public class ConvertStream03 {
        public static void main(String[] args) throws IOException {
            //创建对象
            InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\JavaCode\\code\\codeText01\\src\\text\\IOStream\\ConvertStream\\ConvertStream03\\GBK01.txt"), "GBK");
            FileWriter fw = new FileWriter("D:\\JavaCode\\code\\codeText01\\src\\text\\IOStream\\ConvertStream\\ConvertStream03\\UTF8", Charset.forName("UTF-8"));
            //输入数据
            int b;
            while ((b = isr.read()) != -1) {
                //输出数据
                fw.write((char) b);
            }
    
            //释放资源
            fw.close();
            isr.close();
        }
    }
    
    
  • 输出结果
    • GBK文件(因为idea默认是UTF-8,因此会出现乱码形象)
      在这里插入图片描述
    • UTF-8文件
      在这里插入图片描述

6.2 练习2:读取文件数据

  • 需求:利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码
  • 代码示例
    package text.IOStream.ConvertStream.ConvertStream04;
    
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /*读取文件中的数据
    
    需求:利用字节流读取文件中的数据,每次读一整行,而且不能出现乱码
     */
    public class ConvertStream04 {
        public static void main(String[] args) throws IOException {
            //创建转换流对象
            InputStreamReader isr = new InputStreamReader(new FileInputStream("D:\\JavaCode\\code\\codeText01\\src\\text\\IOStream\\ConvertStream\\ConvertStream04\\a.txt"));
            // 创建缓冲流对象,从而调用readline方法,每次读取一行
            BufferedReader br = new BufferedReader(isr);
            //读取数据
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            //释放资源
            br.close();
            isr.close();
        }
    }
    
    
  • 输出结果
    • a.txt
      在这里插入图片描述
    • 程序输出
      在这里插入图片描述

7. 注意事项

  1. 字符编码一致性:在创建转换流时,应该明确指定字符编码,确保输入流和输出流之间的字符编码保持一致。不同的字符编码可能会导致数据解析错误或产生乱码。

  2. 异常处理:在使用转换流时,需要及时捕获和处理可能抛出的异常,如字符编码不支持等异常,以避免程序崩溃或产生不可预料的错误。

  3. 适当的缓冲处理:转换流本身并不具备缓冲功能,如果需要使用缓冲功能以提高性能,可以考虑在转换流外包装一层缓冲流(如BufferedReader 或 BufferedWriter)来增加缓冲效果。

  4. 流的关闭:在不再需要使用转换流时,应该手动关闭转换流,以释放资源。可以使用 try-with-resources 结构确保转换流在使用完毕后能够被正确关闭。

  5. 性能考量:转换流可能会引入一定的性能开销,特别是在大规模数据处理时,需要对性能进行适当的评估和优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/420064.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring 源码解析

文章目录 前言相关Spring的定义接口整体代码StartupStep contextRefresh this.applicationStartup.start("spring.context.refresh")prepareRefresh()obtainFreshBeanFactory()registerBeanPostProcessors(beanFactory)SpringAOP原码流程EnableAspectJAutoProxyAnno…

基于java+springboot女士电商平台系统源码+文档设计

基于javaspringboot女士电商平台系统源码文档设计 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…

GaussDB跨云容灾:实现跨地域的数据库高可用能力

背景 金融、银行业等对数据的安全有着较高的要求,同城容灾建设方案,在绝大多数场景下可以保证业务数据的安全性,但是在极端情况下,如遇不可抗力因素等,要保证数据的安全性,就需要采取跨地域的容灾方案。 …

【大咖分享】:千帆AppBuilder:我的AI大模型科研搭子

同济子豪兄介绍 不知不觉,我做人工智能科技区博主已经七年了。从斯坦福公开课系列,到精读AI经典论文系列,从编程奇妙夜,到两天搞定AI毕业设计系列。我们为十几万学员,提供人工智能各方向的论文课程、生涯规划、课题辅…

ROS2体系框架

文章目录 1.ROS2的系统架构2.ROS2的编码风格3.细谈初始化和资源释放4.细谈配置文件5.ROS2的一些命令6.ROS2的核心模块6.1 通信模块6.2 功能包6.3 分布式6.4 终端命令和rqt6.5 launch6.6 TF坐标变换6.7 可视化RVIZ 1.ROS2的系统架构 开发者的工作内容一般都在应用层,…

【计算机网络】五种IO模型与IO多路转接之select

文章目录 一、五种IO模型二、非阻塞IO1.fcntl2.实现函数SetNoBlock3.轮询方式读取标准输入 三、I/O多路转接之select1.初识select2.select函数原型3.socket就绪条件4.select的特点5.select缺点6.select使用案例--只读取数据的server服务器1.err.hpp2.log.hpp3.sock.hpp4.select…

游泳耳机哪种款式好?简单6招教你选到高品质机型!

游泳是一项全身性的运动,不仅能帮助我们保持身体健康,还能让我们在水中放松心情,享受水中的乐趣。而音乐则是人们生活中不可或缺的一部分,它能带给我们快乐和力量。当游泳与音乐相结合,游泳耳机应运而生,为…

MySQL-MHA搭建、故障测试

一、架构说明 MHA(Master High Availability)是一个用于 MySQL 主从复制管理和自动故障转移的开源工具集。MHA 的主要目的是提供 MySQL 环境的高可用性和自动故障转移功能,确保在主库发生故障时能够快速切换到备库,降低业务中断时…

机器人组装、充电桩组装行业生产管理MES系统免费用

​随着工业4.0和智能制造的兴起,企业对于生产过程的数字化、智能化需求日益迫切。传统的MES系统实施周期长、成本高,成为许多企业数字化转型的瓶颈。而低代码开发平台的出现为这一问题提供了新的解决思路。 ​一、万界星空科技低代码平台的优势&#xff…

【市工信】2024年青岛市绿色工厂、绿色工业园区等绿色制造示范申报

科大睿智小编从青岛市工信局了解到&#xff0c;为深入贯彻绿色发展理念&#xff0c;牢固树立绿色低碳发展导向&#xff0c;进一步完善绿色制造体系&#xff0c;培育绿色制造先进典型&#xff0c;根据《工业和信息化部关于印发<绿色工厂梯度培育及管理暂行办法>的通知》&a…

nginx出现 “414 request-uri too large”

nginx出现 “414 request-uri too large” 1.修改传参方式 POST 2.字段能变成后端获取就自己获取&#xff0c;不用前端传 3.修改nginx配置&#xff0c;添加client_header_buffer_size 512k;large_client_header_buffers 4 512k;配置

zephyr学习

zephyr内核对象学习 定时器 类似linux的定时器&#xff0c; 可以分别设置第一次到期时间和后续的周期触发时间&#xff0c; 可以注册到期回调和停止回调 还有一个计数状态&#xff0c;用于标记timer到期了多少次 duration&#xff1a;设定timer第一次到期的时间。 period: …

【电机仿真】空间矢量脉宽调制(SVPWM)算法与实现

前言 文章【电机仿真】永磁同步电机模型中所提及了PMSM数学模型&#xff0c;模型算法是电机控制的理论基础&#xff0c;但在实际控制中&#xff0c;需要将这两部分具象化。实际电机所需要的总是三相电流或者电压&#xff0c;控制对象为逆变器中的开关器件&#xff0c;我们需要将…

C/C++ Zlib库调用Minzip来封装MyZip压缩类

文章目录 1、C/C Zlib库调用Minzip来封装MyZip压缩类1.1、类的功能实现1.1.1、ZIP压缩函数 Compress1.1.2、ZIP解压函数 UnCompress1.1.3、代码如下1.1.4、如何使用类 1、C/C Zlib库调用Minzip来封装MyZip压缩类 Zlib是一个开源的数据压缩库&#xff0c;提供了一种通用的数据压…

金仕达与 DolphinDB 建立深度合作,共筑 FICC 科技创新新篇章

从“关起门做交易”到“打开门做服务”&#xff0c;国内 FICC 业务正经历从自营到市场化服务的转变&#xff0c;借助数据分析、算法交易等技术的快速发展&#xff0c;交易团队能够更加主动地发现市场需求&#xff0c;为不同客群提供更好的做市业务&#xff0c;FICC 交易电子化已…

用于制作耳机壳的倒模专用UV树脂有什么特点?

制作耳机壳的UV树脂耳机壳UV胶具有以下特点&#xff1a; 快速固化&#xff1a;UV树脂可以在紫外线的照射下迅速固化&#xff0c;大大缩短了制作时间。高硬度与高耐磨性&#xff1a;UV树脂具有较高的硬度和耐磨性&#xff0c;能够提供良好的保护效果。透明度高&#xff1a;UV树…

靶机渗透之ConnectTheDots

对于vulnhub中的靶机&#xff0c;我们都需先下载镜像&#xff0c;然后导入VM&#xff0c;并将网络连接改为NAT模式。首先我们再来看一下靶机渗透的步骤&#xff1a;信息收集-漏洞分析-漏洞利用-提权。基本都是这个三个步骤&#xff0c;接下来开始我们今天的靶机渗透吧&#xff…

qt QRadioButton 及QButtonGroup 使用

QRadioButton 放在组合框QGroupBox中&#xff0c;再点击时&#xff0c;即使有多个QRadioButton按钮&#xff0c;同时选中的也就只有一个。 如下图所示&#xff0c; 对于多个QRadioButton&#xff0c;每个按钮都写一个槽函数是不太明智的选择&#xff0c;需要将QRadioButton放在…

续上一篇---Jetson Xavier NX 开发板板载摄像头教程

测试摄像头&#xff0c;打开 NX 的终端 写入命令&#xff1a;nvgstcapture-1.0 摄像头就会起来了&#xff0c;想关掉摄像头的话&#xff0c;直接在终端输入 q 再按回车&#xff1b;想捕获图片的话&#xff0c;在终端输入 j 再按回车&#xff0c;图片将保存当前目录下。 手册中…

html基础操练和进阶修炼宝典

文章目录 1.超链接标签2.跳锚点3.图片标签4.表格5.表格的方向属性6.子窗口7.音视频标签8.表单9.文件上传10.input属性 html修炼必经之路—各种类型标签详解加展示&#xff0c;关注点赞加收藏&#xff0c;防止迷路哦 1.超链接标签 <!DOCTYPE html> <html lang"en…