Java中IO流基本介绍(5)——InputStreamReader和OutputStreamWriter

article/2025/11/6 10:43:00

1 基本概括

2 主要介绍

2.1 InputStreamReader/OutputStreamWriter 相比FileReader和FileWriter的优势

前者可以指定读取和写出的编码,不容易出现乱码。

2.2 转换流的作用

 1. 如果目前所 获取到的是一个字节流需要转换字符流使用,这时候就可以使用转换流。  字节流----> 字符流   

 2. 使用转换流可以指定编码表进行读写文件

2.3 编码与解码

1 经常说到编码和解码也就是从字符到字节,或者字节到字符的转换,转换的规则就是按照指定的码表

2 只要理解了码的含义 :指的是二进制的 0 1 的数值序列编码表中都有字符对应的数值序列编码把字符从符号转变成二进制序列就是编码解码就是转换为指定的字符形式。

3 字节流和字符流之间的转换,自然离不开编码与解码计算机最底层数据的存储是二进制序列,也就是字节所以如果是从最底层读取,那么就是涉及二进制到字符的解码从字符写入到最底层,就是字符的编码

2.4 StreamDecoder到底是什么

StreamDecoder继承了Reader,所以他是一个Reader另外他内部又包含了一个InputStream in;

这个in 通过他的forInputStreamReader系列方法,通过入参InputStream进行设置。

2.5 简单总结

1转换流作为适配器的应用,只需要理解目标和被适配角色即可

2 目标就是在外面抛头露面,直接接触使用的形式,被适配角色就是幕后默默奉献的,也就是他们提供了Reader和Writer字符形式的读写操作方式

3 而内部则都是使用被适配角色,字节流的形式进行读写,中间涉及到的编码与解码 则依靠StreamEncoder 和StreamDecoder

3 用例

3.1一个字节流中的字节解码成字符

@Test
public void IOTest1() throws Exception {InputStream in = new FileInputStream("D:/hello.txt");// 读取文件的数据,注意文件编码为UTF-8,防止读取乱码// 将输入的字节流  ------转换成---->  字符流InputStreamReader isr = new InputStreamReader(in);// 读取char[] data = new char[1024];int len = isr.read(data);//读取字符流中的数据,用char[]数组一次性接收System.err.println(new String(data, 0, len));isr.close();
}

3.2 写入的字符编码成字节后写入一个字节流

@Test
public void IOTest2() throws Exception {		OutputStream out = System.err;// 打印到控制台,也可以输出到文件OutputStreamWriter osr = new OutputStreamWriter(out);//输出 往out里面准备写内容,内容在下面String str = "Hello World!";osr.write(str);//写//osr.flush();//如果用于网络传输,记得强制刷新缓冲区,否则输出的数据只停留在缓冲区中,而无法进行网络传输osr.close();//关闭资源
}

3.3 实现了从一个用UTF-8编码的源文件复制数据到一个用GBK编码的目标文件

private static void Utf8ToGbk() {BufferedReader br = null;BufferedWriter bw = null;try {br = new BufferedReader(new InputStreamReader(new FileInputStream("./test.txt"), "utf-8"));bw = new BufferedWriter(new FileWriter("./test/2.txt"));
//            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("./src/res/2.txt")));String str = null;while(null != (str = br.readLine())) {bw.write(str);bw.newLine();}} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(null != bw) {try {bw.close();} catch (IOException e) {e.printStackTrace();}}if(null != br) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}
}

3.4 实现了从一个用GBK编码的源文件复制数据到一个用UTF-8编码的目标文件

 private static void gbkToUtf8() {BufferedReader br = null;BufferedWriter bw = null;try {br = new BufferedReader(new FileReader("./src/res/2.txt"));
//          br = new BufferedReader(new InputStreamReader(new FileInputStream("./test.txt")));//使用默认字符集bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("./test2.txt"), "utf-8"));String str = null;while(null != (str = br.readLine())) {bw.write(str);bw.newLine();}} catch (FileNotFoundException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if(null != bw) {try {bw.close();} catch (IOException e) {e.printStackTrace();}}if(null != br) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}}

4 源码分析

4.1 InputStreamReader 源码

package java.io;import java.nio.charset.Charset;import java.nio.charset.CharsetDecoder;import sun.nio.cs.StreamDecoder;// 将“字节输入流”转换成“字符输入流”public class InputStreamReader extends Reader {private final StreamDecoder sd;// 根据in创建InputStreamReader,使用默认的编码public InputStreamReader(InputStream in) {super(in);try {sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object} catch (UnsupportedEncodingException e) {// The default encoding should always be availablethrow new Error(e);}}// 根据in创建InputStreamReader,使用编码charsetName(编码名)public InputStreamReader(InputStream in, String charsetName)throws UnsupportedEncodingException{super(in);if (charsetName == null)throw new NullPointerException("charsetName");sd = StreamDecoder.forInputStreamReader(in, this, charsetName);}// 根据in创建InputStreamReader,使用编码cspublic InputStreamReader(InputStream in, Charset cs) {super(in);if (cs == null)throw new NullPointerException("charset");sd = StreamDecoder.forInputStreamReader(in, this, cs);}// 根据in创建InputStreamReader,使用解码器decpublic InputStreamReader(InputStream in, CharsetDecoder dec) {super(in);if (dec == null)throw new NullPointerException("charset decoder");sd = StreamDecoder.forInputStreamReader(in, this, dec);}// 获取解码器public String getEncoding() {return sd.getEncoding();}// 读取并返回一个字符public int read() throws IOException {return sd.read();}// 将InputStreamReader中的数据写入cbuf中,从cbuf的offset位置开始写入,写入长度是lengthpublic int read(char cbuf[], int offset, int length) throws IOException {return sd.read(cbuf, offset, length);}// 能否从InputStreamReader中读取数据public boolean ready() throws IOException {return sd.ready();}// 关闭InputStreamReaderpublic void close() throws IOException {sd.close();}}

4.2 OutputStreamWriter 源码

package java.io;import java.nio.charset.Charset;import java.nio.charset.CharsetEncoder;import sun.nio.cs.StreamEncoder;// 将“字节输出流”转换成“字符输出流”public class OutputStreamWriter extends Writer {private final StreamEncoder se;// 根据out创建OutputStreamWriter,使用编码charsetName(编码名)public OutputStreamWriter(OutputStream out, String charsetName)throws UnsupportedEncodingException{super(out);if (charsetName == null)throw new NullPointerException("charsetName");se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);}// 根据out创建OutputStreamWriter,使用默认的编码public OutputStreamWriter(OutputStream out) {super(out);try {se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);} catch (UnsupportedEncodingException e) {throw new Error(e);}}// 根据out创建OutputStreamWriter,使用编码cspublic OutputStreamWriter(OutputStream out, Charset cs) {super(out);if (cs == null)throw new NullPointerException("charset");se = StreamEncoder.forOutputStreamWriter(out, this, cs);}// 根据out创建OutputStreamWriter,使用编码器encpublic OutputStreamWriter(OutputStream out, CharsetEncoder enc) {super(out);if (enc == null)throw new NullPointerException("charset encoder");se = StreamEncoder.forOutputStreamWriter(out, this, enc);}java io系列01之 "目录"// 获取编码器encpublic String getEncoding() {return se.getEncoding();}// 刷新缓冲区void flushBuffer() throws IOException {se.flushBuffer();}// 将单个字符写入到OutputStreamWriter中public void write(int c) throws IOException {se.write(c);}// 将字符数组cbuf从off开始的数据写入到OutputStreamWriter中,写入长度是lenpublic void write(char cbuf[], int off, int len) throws IOException {se.write(cbuf, off, len);}// 将字符串str从off开始的数据写入到OutputStreamWriter中,写入长度是lenpublic void write(String str, int off, int len) throws IOException {se.write(str, off, len);}java io系列01之 "目录"// 刷新“输出流”// 它与flushBuffer()的区别是:flushBuffer()只会刷新缓冲,而flush()是刷新流,flush()包括了flushBuffer。public void flush() throws IOException {se.flush();}// 关闭“输出流”public void close() throws IOException {se.close();}}

 


http://chatgpt.dhexx.cn/article/rbZDlTiR.shtml

相关文章

IO流——InputStreamReader 和 OutputStreamWriter

本次博客来学习IO流中的转换流——InputStreamReader 和 OutputStreamWriter。 InputStreamReader 和 OutputStreamWriter InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成Reader(字符流)。 OutputStreamWriter:Writer的子…

OutputStreamWriter类

1、概述 转换流 java.io.OutputStreamWriter,是Writer的子类,是从字符流到字节流的桥梁。 它使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。 2、继承父类的共性成员方法 该类继承 Writer 类&…

转换流OutputStreamWriter

1、转换流–OutputStreamWriter简介 : OutputStreamWriter extends Writer, 转换流也是继承自超类Writer,因此可以使用Writer中的共性方法:write(int c),write(char[] ch),…,flash(),close(),… OutputStreamWriter常用的构造方法: 1&…

详解OutputStreamWriter与InputStreamReader

1.转换流原理 2. OutputStreamWriter java.io.OutputStreamWriter extends Writer OutputStreamWriter:是字符流通向字节流的桥梁;可使用指定的charset将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂) 2.1 继承自父…

Java IO体系之OutputStreamWriter

介绍 字符输出流Writer 的实现类 继承关系图 样例 public static void main(String[] args) throws IOException{//创建字节输出流,绑定数据文件(没有则创建)FileOutputStream fosnew FileOutputStream("D:\\HELLO.txt");// 创建…

streamwriter java_Java OutputStreamWriter 类

Java OutputStreamWriter 类 在本教程中,我们将借助示例学习Java OutputStreamWriter及其方法。 java.io包的OutputStreamWriter类可用于将字符形式的数据转换为字节形式的数据。 它继承了抽象类Writer。 OutputStreamWriter类可与其他输出流一起使用。 它也被称为字…

40OutputStreamWriter

写的转换流,写我们相要写的编码文件 java.io.OutputStreamWriter etends Writer InputStreamReader是字节流通向字符流的桥梁,它使用指定的Charset 将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂的) 继承…

Java IO 学习总结(五)OutputStreamWriter

Java IO 学习总结(一)输入流/输出流 Java IO 学习总结(二)File 类 Java IO 学习总结(三)BufferedInputStream Java IO 学习总结(四)BufferedReader 缓冲字符流 Java IO 学习总结&…

IO流(学习Java第24天)(转换流OutputStreamWriter、转换流InputStreamReader、字符流便捷类)

目录 一、转换流OutputStreamWriter 二.转换流InputStreamReader 三.字符流便捷类 一、转换流OutputStreamWriter java.io.OutputStreamwriter类,继承Writer类,他是字符输出流,只能操作文本文件,不能操作其他类型文件。Output…

Java IO流学习总结五:转换流-InputStreamReader、OutputStreamWriter

类的继承关系 Reader |__ BufferedReader、StringReader、InputStreamReader|__ FileReaderWriter |__ BufferedWriter、StringWriter、OutputStreamWriter|__ FileWriter InputStreamReader 简介 InputStreamReader 是字符流 Reader 的子类,是字节流通向字符流的桥梁。你…

mysql判断是否存在索引并删除_mysql判断索引存在时删除索引的方法_MySQL

bitsCN.com mysql判断索引存在时删除索引的方法 mysql的drop index语句不支持if exists条件,在sql中先删除索引, 再创建索引,如果对于新建的数据库,库中没有该索引,就会报错, 导致后面的sql不再执行。 因此…

Oracle索引详解(索引的原理,创建索引,删除索引,修改索引等)

Oracle索引详解 一.索引概述 Oracle作为关系型数据库,用户查找数据与行的物理位置无关,表中的每一行均用一个ROWID来标识,当Oracle数据库中存储海量的记录时,就意味着有大量的ROWID标识,那么Oracle如何能快速找到指定…

es批量删除索引

es批量删除索引 ES/DSL语句删除索引中的文档,以时间为过滤条件 执行时如图所示: 请求:sgl_zc_termina_exhaust_20200924/_delete_by_query post DSL风格的语句: { “query”: { “bool”: { “must”: [{ “range”: { “collectTime”: { “gt”: “1616342400000”, “lt”…

Phoenix删除索引

直接在DBeaver的工具中使用Phonix连接hbase,创建索引后,直接右键删除索引,会报错无法删除。 以下提示删除索引的操作: select * from SYSTEM."CATALOG" where TABLE_NAMET5_3D71E0783EE811E9B1C10050569D5D3A AND TABLE_SCHEM MP…

mysql删除索引_SQL基础12:Mysql删除索引

图片发自简书App 学习此文之前,一起先来回顾下Mysql创建索引 简介:在本篇教程中,你将学习如何使用MYSQL DROP INDEX语法删除表中已经存在的索引。 一、MYSQL删除索引的语法 要从表中删除现有索引,可使用DROP INDEX*语句&#xff0…

MySql 删除索引

#删除索引 -- (1)使用alter table 删除 -- 语法:alter table 表名 drop index|key 索引名 -- 列如:删除表book11中的索引 alter table book11 drop index sno -- (2)使用 drop index 删除 -- 语法:drop index 索引名称 on 表名 -- 列如:删除表book…

MySQL——索引的创建与删除

文章目录 MySQL——索引的创建与删除1、创建索引的三种方式1.1、建表时创建索引1.2、修改表时创建索引1.3、使用 CREATE INDEX 语句创建索引 2、删除索引 MySQL——索引的创建与删除 1、创建索引的三种方式 1.1、建表时创建索引 使用CREATE TABLE创建表时,除了可…

c++ 实现meanshift

自己手动实现了meanshift,算是把之前还有些模糊的地方给搞清楚了,本来应该半天就可以的,结果高斯核函数计算权重那里弄错了,多花了好一阵子功夫才搞定。 原理 对于所有样本点中的一个点x,计算它的shift vector&#…

Meanshift均值漂移聚类算法

一、meanshift 均值漂移就是把指定的样本点沿着密度上升的方向移向高密度区域。这里可以用矢量加法的几何意义来理解。参考博文Mean Shift 聚类算法 meanshift为 M r ( x ) 1 k ∑ x i ∈ S r ( x ) ( x i − x ) M_r(x)\frac{1}{k}\sum\limits_{x_i\in S_r(x)}(x_i-x) Mr​…

MeanShift 目标跟踪

MeanShift算法,又称为均值漂移算法,采用基于颜色特征的核密度估计,寻找局部最优,使得跟踪过程中对目标旋转,小范围遮挡不敏感。 文章目录 MeanShift 原理MeanShift 跟踪步骤meanShift 函数原型反向投影MeanShift 跟踪…