转换流详解

在Java中,处理文本数据时,我们经常需要将字节流转换为字符流,或者将字符流转换为字节流。这种转换通常用于读取文本文件或将数据从网络传输到应用程序。Java提供了两种主要的转换流:InputStreamReaderOutputStreamWriter

1 转换流的作用

  • InputStreamReader:将字节输入流转换为字符输入流。
  • OutputStreamWriter:将字符输出流转换为字节输出流。

这两种转换流使用指定的字符集(如UTF-8、GBK、ISO-8859-1等)在字节流和字符流之间进行转换。

2 编码与解码

在计算机中,数据通常以二进制形式存储和传输。编码是将原始数据(如文本、图像、视频、音频等)转换为二进制形式的过程,而解码则是将二进制数据转换回原始数据的过程。常见的编码和解码方式包括:

  • ASCII编码:用于表示英文字母、数字和符号。
  • Unicode编码:支持多种语言和字符集,常见的编码方式有UTF-8、UTF-16等。
  • Base64编码:将二进制数据转换为ASCII字符,常用于网络传输。
  • 图像编码:如JPEG、PNG、GIF等,用于图像的存储和传输。
  • 视频编码:如H.264、AVC、MPEG-4等,用于视频的存储和传输。

简单来说:

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

以下是一个简单的编码和解码示例:

String str = "沉默王二";
String charsetName = "UTF-8";// 编码
byte[] bytes = str.getBytes(Charset.forName(charsetName));
System.out.println("编码: " + bytes);// 解码
String decodedStr = new String(bytes, Charset.forName(charsetName));
System.out.println("解码: " + decodedStr);

在这个示例中,首先定义了一个字符串变量 str 和一个字符集名称 charsetName。然后,使用 Charset.forName() 方法获取指定字符集的 Charset 对象。接着,使用字符串的 getBytes() 方法将字符串编码为指定字符集的字节数组。最后,使用 new String() 方法将字节数组解码为字符串。

需要注意的是,编码和解码过程中必须使用相同的字符集,以确保数据的正确转换。

3 字符集

字符集(Charset)是一组字符的集合,每个字符都有一个唯一的编码值,称为码点。常见的字符集包括:

  • ASCII字符集:包含128个字符,每个字符使用7位二进制编码。
  • Unicode字符集:包含世界上几乎所有的字符,支持多种语言和字符集。常见的编码方式有UTF-8、UTF-16等。
  • GBK字符集:包含GB2312字符集中的字符,并扩展了许多其他汉字字符和符号。

4 乱码问题

当使用不同的编码方式读取或写入文件时,可能会出现乱码问题。例如,将字符串按GBK编码保存到文件中,然后使用UTF-8编码读取文件,就会出现乱码。

以下是一个乱码问题的示例:

String s = "沉默王二!";try {// 将字符串按GBK编码方式保存到文件中OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("logs/test_utf8.txt"), "GBK");out.write(s);out.close();FileReader fileReader = new FileReader("logs/test_utf8.txt");int read;while ((read = fileReader.read()) != -1) {System.out.print((char)read);}fileReader.close();
} catch (IOException e) {e.printStackTrace();
}

在这个示例中,文件中的GBK编码字符在使用UTF-8编码方式解析时无法正确解析,从而导致乱码。

5 使用转换流解决乱码问题

为了解决乱码问题,我们可以使用InputStreamReaderOutputStreamWriter进行字节流和字符流之间的转换。

5.1 InputStreamReader

InputStreamReaderReader类的子类,用于将字节流转换为字符流。它支持指定的字符集编码方式。

构造方法:

  • InputStreamReader(InputStream in):使用默认字符集创建字符流。
  • InputStreamReader(InputStream in, String charsetName):使用指定字符集创建字符流。

常用方法:

  • read():从输入流中读取一个字符的数据。
  • read(char[] cbuf, int off, int len):从输入流中读取len个字符的数据到指定的字符数组 cbuf 中,从 off 位置开始存放。
  • ready():返回此流是否已准备好读取。
  • close():关闭输入流。

示例:

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

解决乱码问题的示例:

String s = "沉默王二!";try {// 将字符串按GBK编码方式保存到文件中OutputStreamWriter outUtf8 = new OutputStreamWriter(new FileOutputStream("logs/test_utf8.txt"), "GBK");outUtf8.write(s);outUtf8.close();// 将字节流转换为字符流,使用GBK编码方式InputStreamReader isr = new InputStreamReader(new FileInputStream("logs/test_utf8.txt"), "GBK");// 读取字符流int c;while ((c = isr.read()) != -1) {System.out.print((char) c);}isr.close();
} catch (IOException e) {e.printStackTrace();
}

在这个示例中,我们使用InputStreamReader将字节流转换为字符流,并指定GBK编码方式,从而避免了乱码问题。

5.2 OutputStreamWriter

OutputStreamWriterWriter类的子类,用于将字符流转换为字节流。它支持指定的字符集编码方式。

构造方法:

  • OutputStreamWriter(OutputStream in):使用默认字符集创建字符流。
  • OutputStreamWriter(OutputStream in, String charsetName):使用指定字符集创建字符流。

常用方法:

  • write(int c):向输出流中写入一个字符的数据。
  • write(char[] cbuf, int off, int len):向输出流中写入指定字符数组 cbuf 中的 len 个字符,从 off 位置开始。
  • flush():将缓冲区的数据写入输出流中。
  • close():关闭输出流。

示例:

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

提高读写效率的示例:

try {// 从文件读取字节流,使用UTF-8编码方式FileInputStream fis = new FileInputStream("test.txt");// 将字节流转换为字符流,使用UTF-8编码方式InputStreamReader isr = new InputStreamReader(fis, "UTF-8");// 使用缓冲流包装字符流,提高读取效率BufferedReader br = new BufferedReader(isr);// 创建输出流,使用UTF-8编码方式FileOutputStream fos = new FileOutputStream("output.txt");// 将输出流包装为转换流,使用UTF-8编码方式OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");// 使用缓冲流包装转换流,提高写入效率BufferedWriter bw = new BufferedWriter(osw);// 读取输入文件的每一行,写入到输出文件中String line;while ((line = br.readLine()) != null) {bw.write(line);bw.newLine(); // 每行结束后写入一个换行符}// 关闭流br.close();bw.close();
} catch (IOException e) {e.printStackTrace();
}

在这个示例中,我们使用缓冲流包装转换流,以提高读写效率。

6 小结

InputStreamReaderOutputStreamWriter是Java中用于字节流和字符流之间转换的重要工具。它们可以帮助我们解决字节流和字符流之间的转换问题,并避免乱码问题。在使用转换流时,务必指定正确的字符集编码方式,以确保数据的正确读取和写入。

7 思维导图

在这里插入图片描述

8 参考链接

Java 转换流:Java 字节流和字符流的桥梁

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

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

相关文章

广东网站设计提升你网站在搜索引擎中的排名

在当今网络盛行的时代,拥有一个设计优良的网站,对企业的在线发展至关重要。特别是对于广东地区的企业来说,网站设计不仅仅是美观的问题,更直接影响着搜索引擎中的排名。因此,精心策划和设计的网站,能够显著…

VisualStudio远程编译调试linux_c++程序(二)

前章讲述了gdb相关,这章主要讲述用VisualStudio调试编译linux_c程序 1:环境 win10 VisualStudio 2022 Community ubuntu22.04 2:安装 1>vs安装时,勾选 使用c进行linux 和嵌入式开发 (这里以vs2022为例) OR VS安装好了, 选择工…

Netty 常见组件介绍

Netty 常见组件介绍 上篇文章Netty入门程序echo 基本包含了Netty常见的组件,本文分别介绍各个组件 Bootstrap or ServerBootstrapEventLoopEventLoopGroupChannelPipelineChannelFuture or ChannelFutureChannelInitializerChannelHandler Bootstrap vs ServerBo…

el-talble selection行 初始默认勾选

导言 el-talble selection 行(选择列)用于显示复选框,让用户可以选择或取消选择某些表格行,常用于批量操作场景。 刚刚试了下,想加深印象记录一下当学习碎片。参考的是表格多选并根据每行值初始化选中状态(…

HTML 块级元素和内联(行内)元素详解

在 HTML 中,元素根据它们在页面中的表现方式分为两类:块级元素 和 内联元素(行内元素)。了解块级元素和内联元素的特性与使用方法,是掌握HTML开发的重要基础。本文将深入探讨这两类元素的特点及其在实际开发中的应用。 文章目录 一、块级元素1.1 块级元素是什么?1.2 块级…

使用Docker构建和部署微服务

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 [TOC] Docker 是一个开源的容器化平台,可以帮助开发者轻松构建、打包和部署应用程序。本文将详细介绍如何使用 Dock…

conda下jupyterlab安装问题以及交互绘图问题记录

安装 1. 直接conda install jupyterlab就好,只要在base环境下安装就行,可以在任意环境下执行jupyter lab启动。 2. 打开jupyter lab后显示Could not determine jupyterlab build status without nodejs,可以执行conda install nodejs安装no…

springcloud整合sentinel,限流策略持久化到nacos,详细配置案例

目录 1.组件下载和启动 (1)sentinel-dashboard下载 (2)nacos下载 (3)jmeter下载 (4)redis下载(与流控关系不大,与项目启动有关) 2.本微服务项…

【ONLYOFFICE 文档 8.2 版本深度测评】功能革新与用户体验的双重飞跃

引言 在数字化办公的浪潮中,ONLYOFFICE 文档以其强大的在线协作功能和全面的办公套件解决方案,赢得了全球用户的青睐。随着 8.2 版本的发布,ONLYOFFICE 再次证明了其在办公软件领域的创新能力和技术实力。 一.协作编辑 PDF:团队合…

Java爬虫:在1688上“照片快递”上传图片

想象一下,你是一名快递小哥,不过你送的不是包裹,而是图片——而且是用Java编写的爬虫作为你的快递车,将图片快速准确地送到1688的服务器上。今天,我们将一起化身为代码界的“照片快递”,使用Java爬虫技术&a…

深入探索ReentrantLock(三):限时锁申请的艺术

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 前言 一、ReentrantLock限时锁申请 1.限时锁申请的必要性 2.tryLock(long time, TimeUnit unit) 方法讲解 3.限时锁的优势与注意事项 4.tryLock(long time, TimeUnit unit)案例 总结 前言 Java并…

初始JavaEE篇——多线程(4):wait、notify,饿汉模式,懒汉模式,指令重排序

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:JavaEE 目录 wait、notify 方法 多线程练习 单例模式 饿汉模式 懒汉模式 指令重排序 wait、notify 方法 wait 和 我们前面学习的sleep…

在线预览 Word 文档

引言 随着互联网技术的发展,Web 应用越来越复杂,用户对在线办公的需求也日益增加。在许多业务场景中,能够直接在浏览器中预览 Word 文档是一个非常实用的功能。这不仅可以提高用户体验,还能减少用户操作步骤,提升效率…

C++ 优先算法 —— 查找总价格为目标值的两个商品(双指针)

目录 题目 :查找总价格为目标值的两个商品 1. 题目解析 2. 算法原理 Ⅰ 暴力枚举 Ⅱ 双指针算法 3. 代码实现 暴力枚举 双指针算法 题目 :查找总价格为目标值的两个商品 1. 题目解析 题目截图: 这道题的一个关键的地方,它先…

Qt QCheckBox、QPushButton和QRadioButton详解

QCheckBox(复选框) 功能:QCheckBox用于创建一个复选框控件,允许用户从多个选项中选择多个。 属性: checkable:决定复选框是否可以被选中或取消选中。checked:表示复选框当前的选中状态&#…

自编以e为底的指数函数exp,性能接近标准库函数

算法描述: (1). 先做自变量x的范围检查,对于双精度浮点数,自变量不能超出(-1022ln2, 1024ln2)(-708.39, 709.78),否则exp(x)会溢出。对于单精度浮点数,自变量不能超出(-126ln2, 128ln2)(-87.33, 88.72). 自己使用此函数…

数据结构-二叉树中的递归

目录 前言 简单手撕二叉树 二叉树节点的求解 二叉树叶子节点的求解 二叉树高度 二叉树第K层节点的个数 二叉树查找值为X的节点 结束语 前言 在这里说声抱歉,好久没更新数据结构了,二叉树的相关内容还没有更新完,是小编的失职&#xff…

在基于AWS EC2的云端k8s环境中 搭建开发基础设施

中间件下载使用helm,这里部署的都是单机版的 aws-ebs-storageclass.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:name: aws-ebs-storageclass provisioner: kubernetes.io/aws-ebs parameters:type: gp2 # 选择合适的 EBS 类型,如 gp2、io1…

2024网鼎杯青龙组wp:Crypto1

题目 附件内容如下 from Crypto.Util.number import * from secret import flag from Cryptodome.PublicKey import RSAp getPrime(512) q getPrime(512) n p * q d getPrime(299) e inverse(d,(p-1)*(q-1)) m bytes_to_long(flag) c pow(m,e,n) hint1 p >> (51…

Golang | Leetcode Golang题解之第528题按权重随机选择

题目&#xff1a; 题解&#xff1a; type Solution struct {pre []int }func Constructor(w []int) Solution {for i : 1; i < len(w); i {w[i] w[i-1]}return Solution{w} }func (s *Solution) PickIndex() int {x : rand.Intn(s.pre[len(s.pre)-1]) 1return sort.Searc…