转换流也是一种处理流,它提供了字节流和字符流之间的转换。在Java IO流中提供了两个转换流:InputStreamReader 和 OutputStreamWriter,这两个类都属于字符流。其中InputStreamReader将字节输入流转为字符输入流,继承自Reader。OutputStreamWriter是将字符输出流转为字节输出流,继承自Writer。


众所周知,计算机中存储的数据都是二进制的数字,我们在电脑屏幕上看到的文字信息是将二进制转换之后显示的,两者之间存在编码解码的过程,其互相转换必须遵循某种规则,即编码和解码都遵循同一种规则才能将文字信息正常显示,如果编码跟解码使用了不同的规则,就会出现乱码的情况。

编码:字符、字符串(能看懂的)--字节(看不懂的)

解码:字节(看不懂的)-->字符、字符串(能看懂的)

上面说的编码与解码的过程需要遵循某种规则,这种规则就是不同的字符编码。我们在刚刚学习编程的时候最早接触就是ASCII码,它主要是用来显示英文和一些符号,到后面还有接触到别的编码规则常用的有:gb2312,gbk,utf-8等。它们分别属于不同的编码集。

我们需要明确的是字符编码和字符集是两个不同层面的概念。

  • encoding是charset encoding的简写,即字符集编码,简称编码

  • charset是character set的简写,即字符集

编码是依赖于字符集的,一个字符集可以有多个编码实现,就像代码中的接口实现依赖于接口一样。

转换流的原理是:字符流=字节流+编码表。在转换流中选择正确的编码非常的重要,因为指定了编码,它所对应的字符集自然就指定了,否则很容易出现乱码,所以编码才是我们最终要关心的。

转换流的特点:其是字符流和字节流之间的桥梁。

可对读取到的字节数据经过指定编码转换成字符

可对读取到的字符数据经过指定编码转换成字节

那么何时使用转换流?

当字节和字符之间有转换动作时

流操作的数据需要编码或解码时


1、InputStreamReader

InputStreamReader是字节流到字符流的桥梁:它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

构造方法:

       · InputStreamReader(InputStream in):创建一个默认字符集字符输入流。

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

构造方法示例代码:

    InputStreamReader isr1 = new InputStreamReader(new FileInputStream("D:\\IO\\utf8.txt"));
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("D:\\IO\\utf8.txt"),"UTF-8");

InputStreamReader读入不同编码举例(读入的文件编码是UTF-8):

package com.thr;

import java.io.*;

/**
* @author Administrator
* @date 2020-02-27
* @desc InputStreamReader
*/
public class InputStreamReaderTest {
public static void main(String[] args) {
//定义转换流
InputStreamReader isr = null;
InputStreamReader isr1 = null; try {
//创建流对象,默认编码方式
isr = new InputStreamReader(new FileInputStream("D:\\IO\\utf8.txt"));
//创建流对象,指定GBK编码
isr1 = new InputStreamReader(new FileInputStream("D:\\IO\\utf8.txt"),"GBK"); //默认方式打印
int len;
char[] buffer = new char[1024];
while ((len=isr.read(buffer))!=-1){
System.out.println(new String(buffer,0,len));
}
//GBK编码方式打印
int len1;
char[] buffer1 = new char[1024];
while ((len1=isr1.read(buffer1))!=-1){
System.out.println(new String(buffer1,0,len1));
} System.out.println("成功...");
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源,先使用的后关闭
if (isr1!=null){
try {
isr1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (isr!=null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
//运行结果:
--UTF-8
武汉加油
中国加油
齐心协力
战胜疫情
--GBK
锘挎姹夊姞娌�
涓浗鍔犳补
榻愬績鍗忓姏
鎴樿儨鐤儏

可以发现,UTF-8编码没有出现乱码,而GBK编码出现了乱码,这是因为是在IDEA编辑器下打印的,我的IDEA编辑器设置的默认编码是UTF-8。而UTF-8的编码集是Unicode,GBK的编码集是GBK,两者并没有通过转换,所以GBK编码在Unicode集上打印出现了乱码。

2、OutputStreamWriter

OutputStreamWriter是字符流通向字节流的桥梁:用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

构造方法:

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

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

构造方法示例代码:

    OutputStreamWriter isr1 = new OutputStreamWriter(new FileOutputStream("D:\\IO\\gbk.txt""));
OutputStreamWriter isr2 = new OutputStreamWriter(new FileOutputStream("D:\\IO\\gbk1.txt") , "GBK");

OutputStreamWriter读出不同编码举例:

package com.thr;

import java.io.*;

/**
* @author Administrator
* @date 2020-02-27
* @desc OutputStreamWriter
*/
public class OutputStreamReaderTest {
public static void main(String[] args) {
//定义转换流
OutputStreamWriter osw = null;
OutputStreamWriter osw1 = null; try {
osw = new OutputStreamWriter(new FileOutputStream("D:\\IO\\gbk.txt"));
osw1 = new OutputStreamWriter(new FileOutputStream("D:\\IO\\gbk1.txt"),"GBK");
//以默认格式写出
osw.write("武汉加油,中国加油");
//以GBK格式写出
osw1.write("武汉加油,中国加油"); System.out.println("成功...");
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源,先使用的后关闭
if (osw1!=null){
try {
osw1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (osw!=null){
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

我们运行完后发现并没有乱码,这是因为Windows系统默认支持了UTF-8和GBK字符集。可以将输出的路径改为当前项目下 new FileOutputStream(“gbk.txt”);然后用Idea打开就可以看成差别来了。

3、转换文件编码

将UTF-8编码的文本文件,转换为GBK编码的文本文件。

1、指定UTF-8编码的转换流,读取文本文件。

2、使用GBK编码的转换流,写出文本文件。

package com.thr;

import java.io.*;

/**
* @author Administrator
* @date 2020-02-27
* @desc 将读入UTF-8文件转换为GBK
*/
public class ConversionStreamTest { public static void main(String[] args) {
//定义转换流
InputStreamReader isr = null;
OutputStreamWriter osw = null; try {
//创建流对象,指定GBK编码
isr = new InputStreamReader(new FileInputStream("D:\\IO\\utf8.txt"),"UTF-8");
osw = new OutputStreamWriter(new FileOutputStream("gbk.txt"),"GBK"); int len;
char[] buffer = new char[1024];
while ((len=isr.read(buffer))!=-1){
osw.write(buffer,0,len);
}
System.out.println("成功...");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
if (osw!=null){
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (isr!=null){
try {
isr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Java IO流详解(六)——转换流的更多相关文章

  1. JAVA IO 类库详解

    JAVA IO类库详解 一.InputStream类 1.表示字节输入流的所有类的超类,是一个抽象类. 2.类的方法 方法 参数 功能详述 InputStream 构造方法 available 如果用 ...

  2. Java IO最详解

    初学java,一直搞不懂java里面的io关系,在网上找了很多大多都是给个结构图草草描述也看的不是很懂.而且没有结合到java7 的最新技术,所以自己来整理一下,有错的话请指正,也希望大家提出宝贵意见 ...

  3. Java io流详解二

    原文地址https://www.cnblogs.com/xll1025/p/6418766.html 一.IO流概述 概述: IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间 ...

  4. 基于JavaSE阶段的IO流详解

    1.IO流基本概述 在Java语言中定义了许多针对不同的传输方式,最基本的就是输入输出流(俗称IO流),IO流是属于java.io包下的内容,在JavaSE阶段主要学下图所示的: 其中从图中可知,所有 ...

  5. IO流详解

    目录 IO流 IO流概述及其分类 IO概念 流按流向分为两种: 流按操作类型分为两种: 常用的IO流类 字节流的抽象父类: 字符流的抽象父类: InputStream & FileInputS ...

  6. java IO流 (五) 转换流的使用 以及编码集

    转换流的使用 1.转换流涉及到的类:属于字符流InputStreamReader:将一个字节的输入流转换为字符的输入流解码:字节.字节数组 --->字符数组.字符串 OutputStreamWr ...

  7. java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET

    java中的io系统详解 - ilibaba的专栏 - 博客频道 - CSDN.NET 亲,“社区之星”已经一周岁了!      社区福利快来领取免费参加MDCC大会机会哦    Tag功能介绍—我们 ...

  8. JAVA IO分析二:字节数组流、基本数据&对象类型的数据流、打印流

    上一节,我们分析了常见的节点流(FileInputStream/FileOutputStream  FileReader/FileWrite)和常见的处理流(BufferedInputStream/B ...

  9. JAVA之旅(二十七)——字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律

    JAVA之旅(二十七)--字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律 我们继续来聊聊I/O 一.字节流的缓冲区 这 ...

  10. Java IO编程全解(六)——4种I/O的对比与选型

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7804185.html 前面讲到:Java IO编程全解(五)--AIO编程 为了防止由于对一些技术概念和术语 ...

随机推荐

  1. PP: Data-driven classification of residential energy consumption patterns by means of functional connectivity networks

    Purpose Implement a good user aggregation and classification. or to assess the interrelation pattern ...

  2. C++分割string字符串(转)

    原文链接:https://blog.csdn.net/jirryzhang/article/details/80473032 或:https://www.cnblogs.com/dingxiaoqia ...

  3. 剑指offer 面试题. 按之字形顺序打印二叉树

    题目描述 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推.   方法1: 正常层次遍历,利用普通队列.逢 ...

  4. codeforce D. White Lines

    二维前缀和 给你一个n*n的矩阵,里面有两种字符,‘W’和‘B’,代表black 和white .其实这个矩阵就是一个方形画板,你有一个k*k的橡皮只能用一次,使k*k的矩阵里的B变成W,问完全空白的 ...

  5. js判断有无属性及新添属性

    1.Object 判断有无新属性 obj.hasOwnProperty(propertyName)  //有无指定属性propertyName        Object.keys(obj)      ...

  6. webpack4.41.0配置二(加载器_url-loader/babel-loader/sass-loader)

    loader是webpack用来预处理源文件的,比如typesrcipt形式的文件最终都得转成浏览器可以执行的js文件 (注:以下的配置代码不一定与下方一摸一样,具体与官网上https://webpa ...

  7. php preg正则表达式的组成部分

    定界符号 : 多种都可以,常用为// 原子 : 最小的一个匹配单位 (放在定界符中),在一个正则表达式中,至少要有一个原子 1,打印字符(a-z A-Z 0-9 ~!@#$%^&*()_+.. ...

  8. 【做题笔记】[NOIOJ,非NOIp原题]装箱问题

    题意:给定一些矩形,面积分别是 \(1\times 1,2\times 2,3\times 3,4\times 4,5\times 5,6\times 6\).您现在知道了这些矩形的个数 \(a,b, ...

  9. 静态方法使用synchronized修饰.

    package seday10;/** * @author xingsir * 静态方法若使用synchronized修饰,这个方法一定具有同步效果.静态方法上使用的同步监视器对象为这个类的" ...

  10. Can't bind to 'ngModel' since it isn't a known property of 'input'.

    angular项目启动报错 Can't bind to 'ngModel' since it isn't a known property of 'input'. 原因:当前module模块未引入 ' ...