File类与常用IO流第九章——转换流
第九章、转换流
字节编码和字符集
编码:按照某种规则将字符以二进制存储到计算机中。
解码:将存储在计算机中的二进制数按照某种规则解析显示出来。
字符编码:Character Encoding ,就是一套自然语言与二进制数之间的对应规则。
字符集: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辅助字符,使用四字节编码。
以上为直接复制的内容
编码引出的问题——FileReader读取项目中的文本文件
ANSI就是系统默认编码,在中国,是GBK
由于IDEA的设置,都是默认的 UTF-8 编码,所以没有任何问题。但是,当读取Windows系统中创建的文本文件时,由于Windows系统的默认是GBK编码,就会出现乱码。
- 1 import java.io.FileReader;
- 2 import java.io.IOException;
- 3
- 4 /*
- 5 FileReader可以读取IDE默认编码格式(UTF-8)的文件
- 6 FileReader读取系统默认编码(中文GBK)会产生乱码���
- 7 */
- 8 public class Demo01FileReader {
- 9 public static void main(String[] args) throws IOException {
- 10 FileReader fr = new FileReader("E:\temp\\我是GBK格式的文本.txt");
- 11 int len = 0;
- 12 while((len = fr.read())!=-1){
- 13 System.out.print((char)len);
- 14 }
- 15 fr.close();
- 16 }
- 17 }
- 文件 我是GBK格式的文本.txt ,保存时选择 ANSI 格式
转换流的原理
API文档中对类 FileReader 有这样的描述:用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小是适当的。要自己指定这些值,可以先在 FileInputStram 上构造一个InputStreamReader。它的的构造方法是这样的:
- public FileReader(String fileName) throws FileNotFoundException { super(new FileInputStream(fileName));}
InputStreamReader是字节流通向字符流的桥梁:它使用指定的 cahrset读取字节并将其解码为字符,如下图所示:
OutputStreamWriter
java.io.OutputStreamWriter extends Writer,是字符流通向字节流的桥梁,可使用指定的charset将要写入流中的字符编成字节。(编码:把能看懂的变成看不懂的)。
构造方法:
OutputStreamWriter(OutputStream out)
OutputStreamWriter(OutputStream out,String charsetName)
构造的参数:
OutputStream out:字节输出流,可以用来写转换之后的字节到文件中。
String charsetName:指定的编码表名称,不区分大小写。不指定则默认使用UTF-8
继承自父类的方法:
void write(int c)
void write(char[] cbuf)
abstract void write(char[] cbuf,int off,int len)
void write(String str)
void write(String str,int off,int len)
void flush()
void close()
使用步骤:
创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称;
使用Osw对象中的方法write,把字符转换为字节存储在缓冲区中(编码);
使用Osw对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字的过程);
释放资源。
代码:
- 1 /*
- 2 使用转换流OutputStreamWriter写GBK格式的文件
- 3 */
- 4 private static void write_gbk() throws IOException {
- 5 //1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
- 6 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\gbk.txt"),"GBK");
- 7 //2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
- 8 osw.write("你好");
- 9 //3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
- 10 osw.flush();
- 11 //4.释放资源
- 12 osw.close();
- 13 }
- 1 /*
- 2 使用转换流OutputStreamWriter写UTF-8格式的文件
- 3 */
- 4 private static void write_utf_8() throws IOException {
- 5 //1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称
- 6 //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"),"utf-8");
- 7 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8
- 8 //2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)
- 9 osw.write("你好");
- 10 //3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)
- 11 osw.flush();
- 12 //4.释放资源
- 13 osw.close();
- 14 }
InputStreamReader
java.io.InputStreamReader extends Reader,是字节流通向字符流的桥梁,它使用指定的charset读取字节并将其解码为字符。(解码:把看不懂的编程可以看懂的。)
构造方法:
InputStreamReader(InputStream in)
InputStreamReader(InputStream in,String charsetName)
构造方法的参数;
in:字节输入流,用来读取文件中保存的字节。
charsetName:指定的编码表名称,不区分大小写,可以是 utf-8/UTF-8,也可以是gbk/GBK,。。。不指定则默认使用UTF-8。
继承自父类的方法:
int read()
in read(char[] cbuf)
void close()
使用步骤:
创建InputStreamReader对象,构造方法传递字节输入流和指定的编码表名称。
使用Isr对象中的方法read读取文件。
释放资源。
注意事项:
构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码。
代码:
- 1 /*
- 2 使用InputStreamReader读取GBK格式的文件
- 3 */
- 4 private static void read_gbk() throws IOException {
- 5 //1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
- 6 //InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"UTF-8");//???
- 7 InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"GBK");//你好
- 8
- 9 //2.使用InputStreamReader对象中的方法read读取文件
- 10 int len = 0;
- 11 while((len = isr.read())!=-1){
- 12 System.out.println((char)len);
- 13 }
- 14 //3.释放资源
- 15 isr.close();
- 16 }
- 1 /*
- 2 使用InputStreamReader读取UTF-8格式的文件
- 3 */
- 4 private static void read_utf_8() throws IOException {
- 5 //1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称
- 6 //InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"),"UTF-8");
- 7 InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8
- 8 //2.使用InputStreamReader对象中的方法read读取文件
- 9 int len = 0;
- 10 while((len = isr.read())!=-1){
- 11 System.out.println((char)len);
- 12 }
- 13 //3.释放资源
- 14 isr.close();
- 15 }
转换文件编码
要求:将GBK编码的文本文件,转换为UTF-8编码的文本文件。
分析:
创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK;
创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8;
使用isr对象中的方法read读取文件;
使用osw对象中的方法write,把读取到的数据写入到文件中;
释放资源。
代码实现有异常则抛出:
- 1 //1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK
- 2 InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\我是GBK格式的文本.txt"),"GBK");
- 3 //2.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8
- 4 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\我是utf_8格式的文件.txt"),"UTF-8");
- 5 //3.使用InputStreamReader对象中的方法read读取文件
- 6 int len = 0;
- 7 while((len = isr.read())!=-1){
- 8 //4.使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中
- 9 osw.write(len);
- 10 }
- 11 //5.释放资源
- 12 osw.close();
- 13 isr.close();
File类与常用IO流第九章——转换流的更多相关文章
- File类与常用IO流第四章——IO字节流
一切文件在存储时,都是以二进制数字的形式保存的,都是一个一个字节.无论使用什么样的流对象,底层传输的始终是二进制数据. 字节输出流 OutputStream java.io.OutputStream ...
- File类与常用IO流第一章File类
第一章:File类 一.1个重点单词: file:文件:directory:文件夹/目录:path:路径(绝对路径:absolutePath) 二.4个静态成员变量: 1.static String ...
- File类与常用IO流第二章过滤器
在第一章中,有一个练习使用递归搜索文件 1 public static void main(String[] args) { 2 File f=new File("E:\\aaa" ...
- File类与常用IO流第七章——Properties集合
Properties概述 java.util.Properties extends Hashtable<k,v> implements Map<k,v> Properties类 ...
- File类与常用IO流第八章——缓冲流
第八章.缓冲流 缓冲流概述 缓冲流,也叫高效流,是对4个基本的FileXxx流的增强.按照数据类型分为4类: 输入缓冲流 输出缓冲流 字节缓冲流 BufferedInputStream Buffe ...
- File类与常用IO流第十一章——打印流
第十一章.打印流 概述:java.io.PrintStream extends OutputStream,为其他输出流添加了功能,使题目能够方便的打印各种数据值表示形式. 特点: 只负责数据的输出,不 ...
- File类与常用IO流第五章——IO字符流
字符流,只能操作文本文件,不能操作图片.视频等非文本文件 字符输入流 java.io.Reader 字符输入流中一些共性的成员方法 int read():读取单个字符并返回. int read(cha ...
- File类与常用IO流第六章——使用try...catch...finally处理流中的异常
在JDK1.7之前: 1 package com.itheima.demo06.trycatch; 2 3 import java.io.FileWriter; 4 import java.io.IO ...
- File类与常用IO流第三章IO流概述
一:以内存为基准,按照数据的流动方向,流向内存为输入(读取数据),流出内存为输出.IO流有四大顶级父类: IO流四大顶级父类 输入流 输出流 字节流 字节输入流 InputStream 字节输出流 ...
随机推荐
- 旷视MegEngine基本概念
旷视MegEngine基本概念 MegEngine 是基于计算图的深度神经网络学习框架. 本文简要介绍计算图及其相关基本概念,以及它们在 MegEngine 中的实现. 计算图(Computation ...
- Cuda Stream流分析
Cuda Stream流分析 Stream 一般来说,cuda c并行性表现在下面两个层面上: Kernel level Grid level Stream和event简介 Cuda stream是指 ...
- noip模拟8[星际旅行·砍树·超级树·求和]
也不能算考得好,虽然这次A了一道题,但主要是那道题太简单了,没啥成就感,而且有好多人都A掉了 除了那一道,其他的加起来一共拿了25pts,这我能咋办,无奈的去改题 整场考试的状态并不是很好啊,不知道是 ...
- Mysql 面试题(一网打尽,收藏版)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- SQL 查询语句总是先执行 SELECT?你们都错了
很多 SQL 查询都是以 SELECT 开始的.不过,最近我跟别人解释什么是窗口函数,我在网上搜索"是否可以对窗口函数返回的结果进行过滤"这个问题,得出的结论是"窗口函数 ...
- 简单聊聊Ehcache缓存
最近工作没有那么忙,有时间来写写东西.今年的系统分析师报名已经开始了,面对历年的真题,真的难以入笔,所以突然对未来充满了担忧,还是得抓紧时间学习技术. 同事推了一篇软文,看到了这个Ehcache,感觉 ...
- Vue开发项目全流程
只记录vue项目开发流程,不说明怎样安装node和vue-cli等 确认安装 安装好node之后,可查看是否安装成功,有版本则安装成功.输入node -v 查看vue是否安装成功,有版本则安装成功.输 ...
- sql数据库新建作业,新建步骤时报错从 IClassFactory 为 CLSID 为 {AA40D1D6-CAEF-4A56-B9BB-D0D3DC976BA2} 的 COM 组件创建实例失败,原因是出现以下错误: c001f011。 (Microsoft.SqlServer.ManagedDTS)
简单粗暴的重启sql数据库 其他网上找的方法 32位操作系统: 打开运行(命令提示符), 一.输入 cd c:\windows\system32 进入到c:\windows\system32路径中 二 ...
- 01-Tkinter教程-窗口的管理与设置
Tkinter介绍 官方用的GUI工具包--Tkinter(IDLE就是用这个开发的). Tkinter是Python的标准GUI库,它实际是建立在Tk技术上的.在大多数Unix平台以及Windows ...
- Spring学习日记01_IOC_xml的三种注入方式
什么是IOC 控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理 使用IOC目的:为了耦合度降低 做入门案例就是IOC实现 IOC底层原理 xml解析 工厂模式 反射 原始方式 cla ...