IO流(3)—转换流与打印流

news2024/9/19 10:45:13

目录

1. 为什么要用到转换流?

2. 字符输入转换流(重点掌握)

3. 字符转换输出流(理解即可)

4. 认识打印流

5. 打印流的作用

6. PrintStream如何使用?

7. PrintStream 内部没有缓冲区

8. PrintWriter如何使用?

9. PrintStream和PrintWriter的区别?


1. 为什么要用到转换流?

我们都知道,字符集编码的格式多种多样,有UTF-8,UTF-16,GBK等等很多种,那么在读取的时候也会有差异,例如我们的IDEA编码格式为UTF-8,当我们去读取一个编码格式为GBK的文件时,即便是采用字节流全部读取出来,也会读取到一堆乱码。

如下所示,我在项目目录下创建一个名为 test02.txt 的文件,随便填写一些内容,将该文件的编码格式改为GBK。

然后我们去另一个编码为UTF-8 的类中编写一个 main 函数,读取该文件中的内容,代码如下所示

public static void main(String[] args) {
        try (
                // 创建 IO流 管道,得到原始字节流对象 is
                Reader r = new FileReader("user-service/test02.txt");

                // 这里我们可以多做一步,将is 对象加工成缓冲流对象提高读写效率
                BufferedReader br = new BufferedReader(r);
        ){

            // 定义一个字符串接收读取到的文件内容
            String line;

            // 将读取到每一行文件内容赋值给字符串 line,这里其实是在底层新建字符串
            while ( (line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 运行上述方法,可以得到如下结果

在控制台,我们可以看到文件中的内容虽然被读取出来,却含有一部分乱码,原因就是因为我们读取的文件编码格式为 GBK,而我们 编写的main 方法编码格式为 UTF-8,编码格式不匹配,就会出现乱码问题。

这还仅仅只是向内存中读数据(即输入流编码格式的问题),如果从内存向硬盘写数据,想要编写的文件编码格式也不一样,该怎么办呢?有没有什么办法可以解决这个问题呢?这就需要用到我们的转换流。

2. 字符输入转换流(重点掌握)

字符转换输出流,在我们开发时还是较为常用的,因为我们在编码时,可能会遇到各种各样类型的文件,需要读入到内存进行处理,这个时候我们就需要使用字符输入转换流进行编码修改。

如图所示,字符输出转换流有两个构造器,我们常用的是第二个圈起来的,他的参数列表中第二个参数可以传入一个String 类型的编码字符串,这里就是要写我们所读取文件的编码格式。

再回到刚才的那个问题,我们使用字符转换输入流来试一下看看是否能够解决乱码问题,我已经写好了代码如下

public static void main(String[] args) {
        try (
                // 创建 IO流 管道,得到原始字节流对象 is
                InputStream is = new FileInputStream("user-service/test02.txt");

                // 将is 字节流转换成字符输入流对象
                InputStreamReader isr = new InputStreamReader(is, "GBK");

                // 这里我们可以多做一步,将isr 对象加工成缓冲流对象提高读写效率
                BufferedReader br = new BufferedReader(isr);
        ){

            // 定义一个字符串接收读取到的文件内容
            String line;

            // 将读取到每一行文件内容赋值给字符串 line,这里其实是在底层新建字符串
            while ( (line = br.readLine()) != null){
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

运行此方法,我们到控制台查看输出结果

 此时可以看到,刚才的乱码问题已经得到了解决。

这里需要提醒一点,在JDK11以后,这种方法就已经用的不多了。因为在JDK11以后,FileReader中又新增了一种构造器,可以额外添加一个字符集编码参数,所以FileWriter也可以用作转换流了,但这是在JDK11以后,用JDK8的还要使用 InputStreamReader 转换流。

3. 字符转换输出流(理解即可)

字符转换输出流相比于字符转换输入流,用的就没有那么多了,所以理解即可,但能熟练掌握最好。

刚才我们也他提到了,字符输入转换流可以控制改变写入到内存中的文件编码格式,那么字符转换输出流也是同样的道理,可有控制我们输出数据的编码格式。

如下图中即为字符转换输出流的构造器,我们常用的同样也是第二个可以传递编码格式参数的构造方法。

下面我简单做个小案例,将刚才 字符转换输入流中的test02.txt 文件中的内容复制一份,但编码格式仍然采用 GBK的形式

public static void main(String[] args) {
        try (
                // 创建 IO 输入流管道,得到原始字节流对象 is
                InputStream is = new FileInputStream("user-service/test02.txt");

                // 将is 字节流转换 成 字符转换输入流对象
                InputStreamReader isr = new InputStreamReader(is, "GBK");

                // 这里我们可以多做一步,将isr 对象加工成缓冲流对象提高 读的效率
                BufferedReader br = new BufferedReader(isr);

                // 创建 IO 输入流管道,得到原始字节流对象 os
                OutputStream os = new FileOutputStream("user-service/test03.txt");

                // 将os 字节流转换成字符转换输出流对象
                OutputStreamWriter osw = new OutputStreamWriter(os,"GBK");

                // 这里我们可以多做一步,将osw 对象加工成缓冲流对象提高 写的效率
                BufferedWriter bw = new BufferedWriter(osw);

        ){

            // 定义一个字符串接收读取到的文件内容
            String line;

            // 将读取到每一行文件内容赋值给字符串 line,这里其实是在底层新建字符串
            while ( (line = br.readLine()) != null){
                osw.write(line,0,line.length());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

运行上述代码,我们都可以在项目木块中找到已经被新建出来的test03.txt文件

这里需要提醒一点,在JDK11以后,这种方法就已经用的不多了。因为在JDK11以后,FileWriter中又新增了一种构造器,可以额外添加一个字符集编码参数,所以FileWriter也可以用作转换流了,但这是在JDK11以后,用JDK8的还要使用 OutputStreamWriter 转换流。

4. 认识打印流

如下图所示,打印流一共有两个,一个是PrintStream,一个是PrintWriter,分别是OutputStream与Writer的子类。

5. 打印流的作用

打印流的作用其实很简单,我们知道,我们使用字节流在打印数据时,如果输出数字97,那么它实际打印的并不是97,而是97对应的ASCLL码表中的字母,就是a;如果我们真的只是想打印数字97,就可以使用打印流,它可以实现我们写什么它就打印什么的功能。

6. PrintStream如何使用?

下图即为PrintStream提供的构造器

 这里还有PrintStream常用的两个方法

PrintStream的使用非常简单,我们只需要直接创建它的对象即可,如下代码所示

public static void main(String[] args) {
        try (
                PrintStream ps = new PrintStream("user-service/test04.txt");
        ){
            ps.print(97);
            ps.print("abcdefg");
            ps.println("中国万岁");
            ps.println(88.888);
            ps.println(true);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

运行此方法,程序会自动创建名为 test04.txt 的文件,可以看到,这里可以添加诸多内容,证书,字符串,浮点数,布尔类型都可以加入,我们打开文件查看如下,可以看到添加成功

7. PrintStream 内部没有缓冲区

PrintStream 字节流底层没有缓冲区,开不开自动刷新都一样。

 8. PrintWriter如何使用?

其实从使用上来讲,PrintStream与PrintWriter没有什么本质的区别,它们的功能都是为了打印数据,但PrintWriter毕竟是字符输出流,所以它可以打印字符串,这里用法就不再作演示了,几乎和PrintStream一摸一样。

9. PrintStream和PrintWriter的区别?

(1)从功能上来讲,PrintStream和PrintWriter都是一样的,都是使用方便,性能高效,这也是它们的核心功能。

(2)PrintStream继承字节输出流OutputStream,因此支持写字节数据的方法。

(3)PrintWriter继承字符输出流Writer,因此支持写字符数据。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

四、Spring源码-DI的过程

Spring源码-DI的过程 接下来我们分析下Spring源码中Bean初始化过程中的DI过程。也就是属性的依赖注入。 一、构造参数依赖 1. 如何确定构造方法 在Spring中生成Bean实例的时候默认是调用对应的无参构造方法来处理。 Component public class BeanK {private BeanE beanE;priv…

LUN映射出错导致写操作不互斥的服务器数据恢复案例

服务器数据恢复环境: 某公司的光纤SAN存储系统,6块硬盘组建一组RAID6,划分若干LUN,MAP到不同的SOLARIS操作系统服务器上。 服务器故障&分析: 由于业务增长需要新增应用,工作人员增加了一台IBM服务器&am…

共享麻将室开启无人值守新潮流

共享麻将室是指一种基于共享经济模式,将麻将室资源进行共享的服务,为用户提供舒适、方便的娱乐场所。通过共享麻将室,用户可以按需预约和使用麻将室,享受社交娱乐的同时,减少了个人投资和管理麻将室的成本。 相比传统麻…

kotlin 编写一个简单的天气预报app(二)增加搜索城市功能

增加界面显示openweathermap返回的信息。 在activity_main.xml里增加输入框来输入城市&#xff0c;在输入款旁边增加搜索按钮来进行查询。 然后原来显示helloworld的TextView用来显示结果。 1. 增加输入城市名字的EditText <EditTextandroid:id"id/editTextCity"…

puppeteer代理的搭建和配置

puppeteer代理的搭建和配置 本文深入探讨了Puppeteer在网络爬虫和自动化测试中的重要角色&#xff0c;着重介绍了如何搭建和配置代理服务器&#xff0c;以优化Puppeteer的功能和性能。文章首先介绍了Puppeteer作为一个强大的Headless浏览器自动化工具的优势和应用场景&#xf…

【嵌入式学习笔记】嵌入式入门1——GPIO

1.什么是GPIO General Purpose Input Output&#xff0c;即通用输入输出端口&#xff0c;简称GPIO&#xff0c;作用是负责采集外部器件的信息或者控制外部器件工作&#xff0c;即输入输出。 2.STM32 GPIO简介 2.1.GPIO特点 不同型号&#xff0c;IO口数量可能不一样&#x…

企业如何在线编写一份优秀的产品说明文档?

编写一份优秀的产品说明文档对于企业来说非常重要&#xff0c;它可以帮助用户理解产品的功能、使用方法和优势&#xff0c;提高用户体验和满意度。下面是一些关键的步骤和建议&#xff0c;帮助企业在线编写一份优秀的产品说明文档。 一、明确目标受众 在编写产品说明文档之前…

搞活系列-Java NIO之偏偏不用buffer.flip()会出现什么问题?

最近看博客又看到了Java NIO相关的博客&#xff0c;其中有讲解NIO和传统IO关于文件复制的文章&#xff0c;看到了如下的代码&#xff1a; /**** channel用例* 基于channel的文件复制*/Testpublic void fileCopyByChannel(){try {FileInputStream fileInputStream new FileInpu…

MyBatis小记_one

目录 什么是框架 1.框架的概述 2.框架要解决的问题 3. 软件开发的分层重要性 4.分层开发的常见框架 MyBatis 框架概述 JDBC 编程的回顾 JDBC 问题分析 MyBatis 框架快速入门 1.官网下载MyBatis框架jar包 2.搭建MyBatis 开发环境 3. 编写持久层接口的映射文件 IUserD…

Stable Diffusion 使用教程

环境说明&#xff1a; stable diffusion version: v1.5.1python: 3.10.6torch: 2.0.1cu118xformers: N/Agradio: 3.32.0 1. 下载 webui 下载地址&#xff1a; GitHub stable-diffusion-webui 下载 根据自己的情况去下载&#xff1a; 最好是 N 卡&#xff1a;&#xff08;我的…

计数排序算法

计数排序 计数排序说明&#xff1a; 计数排序&#xff08;Counting Sort&#xff09;是一种非比较性的排序算法&#xff0c;它通过统计元素出现的次数&#xff0c;然后根据元素出现的次数将元素排列在正确的位置上&#xff0c;从而实现排序。计数排序适用于非负整数或者具有确…

使用vue creat搭建项目

一、查看是否安装node和npm&#xff08;显示版本号说明安装成功&#xff09; node -v npm -v 显示版本号说明安装成功&#xff0c;如果没有安装&#xff0c;则需要先安装。 二、安装vue-cli脚手架 查看安装的版本&#xff08;显示版本号说明安装成功&#xff09; vue -V 三…

纯JS+Vue实现一个仪表盘

在使用canvas的时候发现数值变化&#xff0c;每次都要重新渲染&#xff0c;值都从0开始&#xff0c;这和我的需求冲突。 1. 先绘制基本的圆环背景&#xff0c;利用border-color和border-radius将正方形变成基本的圆环。 <div class"circle"><div class&qu…

使用toad对数据进行分箱处理

Toad 是专为工业界模型开发设计的Python工具包&#xff0c;特别针对评分卡的开发。Toad 的功能覆盖了建模全流程&#xff0c;从 EDA、特征工程、特征筛选到模型验证和评分卡转化。Toad 的主要功能极大简化了建模中最重要最费时的流程&#xff0c;即特征筛选和分箱。 导入模型包…

7 网络通信(上)

文章目录 网络通信概述ip地址ip的作用ip地址的分类私有ip 掩码和广播地址 linux 命令&#xff08;ping ifconfig&#xff09;查看或配置网卡信息&#xff1a;ifconfig(widows 用ipconfig)测试远程主机连通性&#xff1a;ping路由查看 端口端口是怎样分配的知名端口动态端口 查看…

思维导图在线生成,新手必备!

思维导图是一个很好的学习和工作的方式&#xff0c;可以解决我们工作中的很多困难的问题&#xff0c;但是现在随着思维导图学习方法的推广&#xff0c;市面上的导图软件层出不穷&#xff0c;电子化的思维导图软件极大的方便了我们的工作和生活&#xff0c;下面我们就一起来盘点…

Linux下Pycharm安装

查看java版本&#xff0c;如果没有安装&#xff0c;需要先安装Java JDK。 java -versionsudo apt install openjdk-11-jre-headless下载Pycharm社区般&#xff0c;安装。 tar -zxvf pycharm-community-2023.2.tar.gz sh /opt/software/pycharm-community-2023.2/bin/pycharm.s…

URL存储解锁数据管理的新思路,重新定义数据传输与共享(@vue/repl)

Thinking系列&#xff0c;旨在利用10分钟的时间传达一种可落地的编程思想。 近日&#xff0c;在了解 vue/repl 相关内容&#xff0c;其通过 URL 进行数据存储&#xff0c;感觉思路惊奇&#xff0c;打开了新方式。 首先&#xff0c;通过 URL 存储最大的便利是&#xff1a;无需服…

IDEA中连接虚拟机 管理Docker

IDEA中连接虚拟机 管理Docker &#x1f4d4; 千寻简笔记介绍 千寻简笔记已开源&#xff0c;Gitee与GitHub搜索chihiro-notes&#xff0c;包含笔记源文件.md&#xff0c;以及PDF版本方便阅读&#xff0c;且是用了精美主题&#xff0c;阅读体验更佳&#xff0c;如果文章对你有帮…

android 如何分析应用的内存(十三)——perfetto

android 如何分析应用的内存&#xff08;十三&#xff09; 本篇文章是native内存的最后一篇文章——perfetto perfetto简介 从2018年始&#xff0c;android开发者峰会正式推出perfetto工具。从此perfetto成为安卓最重要的工具之一。在2018年以前&#xff0c;android使用syst…