6.4(java学习笔记)转换流
一、乱码问题
我们来看下列例子:
public class ConStream {
//当前平台默认采用GBK
public static void main(String[] args){
String str = "依风";
byte[] by = new byte[48];
byte[] bz = new byte[48];
try {
by = str.getBytes("UTF-8");//设置编码方式为utf-8,即将依风以utf-8的个数转换为byte
bz = str.getBytes("GBK");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(new String(by));//解码,默认采用平台默认格式,此处为GBK,与编码格式不同会产生乱码
System.out.println(new String(bz,0,3));//编码与解码采用格式相同,但解码的字节缺少,会出现乱码
System.out.println(new String(bz));//编码解码格式相同,且字符为缺少,解码正常不会出现乱码
}
}
运行结果:
渚濋
依?
依风
eclipse采用的编码格式,在菜单栏点击Windows-->Preferences-->General-->Workspace 查看默认编码方式

可以看到上面出现乱码的主要原因有两个:
1.编码和解码格式不统一。
2.字节丢失。
而转换流主要就是解决第一个问题的,它可以在读取和写入时指定编码格式,这样统一后就可以避免乱码问题。
二、 InputStreamReader & OutputStreamWtriter
InputStreamReader是从字节流到字符流的桥梁:它读取字节并使用指定的字符集(UTF-8、GBK等)将它们解码成字符。
OutputStreamWriter是从字符流到字节流的桥梁:写入其中的字符使用指定的字符集(UTF-8、GBK等)编码为字节。
三、构造方法
OutputStreamWriter(OutputStream out, String charsetName)
InputStreamReader(InputStream in, String charsetName)
初始化传递进去的是输入输出流对象,charseName是指定的编码格式。
剩下的操作方法与输入输出流类似。
四、例子
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter; public class ConStream {
public static void main(String[] args){
// File f = new File("F:\\依风\\Desktop\\UTF-8.txt");
File f = new File("F:\\依风\\Desktop\\test.txt");
String write = "依风\n依风\n依风";
String read;
try {
char []c = new char[1024];
//字节输入输出流-->转换流-->字符缓冲流
//以一种编码格式写入
OutputStream w = new FileOutputStream(f);
OutputStreamWriter ow = new OutputStreamWriter(w,"GBK");//将字符转换为GBK格式的字节码并写入
BufferedWriter buffW = new BufferedWriter(ow);
buffW.write(write);
buffW.flush();
buffW.close();
w.close();
//将写入的数据
InputStream r = new FileInputStream(f);//字节流
InputStreamReader ir = new InputStreamReader(r,"UTF-8");//将读入GBK格式的字节码,并用UTF-8格式转换为字符
BufferedReader buffR = new BufferedReader(ir);//字符缓冲流
while(null != (read = buffR.readLine())){
System.out.println(read);
}
buffR.close();
r.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:
????
????
????
先将字符串以GBK方式编码成字节,然后将GBK格式的字节写入文件。
然后将GBK格式的字节以UTF-8格式解码成字符。
上列代码运行后显示的是乱码,因为写入和读取采用的编码方式不一样。
看个图更好理解:

可见转换流主要就两个功能:
1、字节流与字符流字节转换的桥梁
2、指定字节转换为字符的编码方式
如果把上述代码中的读、写编码格式一致,则不会出现乱码。反之则会出现乱码。
还要一点需要注意:
文件打开时采取的解码方式与程序写入时的编码方式无关。
举个例子,假如我是将字符串转换为GBK格式的字节,然后将GBK格式的字节写入记事本(*.txt)。
我们打开记事本时记事本首先要解码(将二进制的字节转换为字符),但此时采用的解码规则不一定是GBK。
可能是GBK,也可能是UTF-8。记事本采取的解码规则是记事本本身绝对的,记事本会根据本身存储的字节信息进行判断,
然后选取对应的编码,这个判断大多数情况下时准确的但也有例外。
例如在记事本中写入“连通”,然后另存为指定下编码规则为ANSI,即在windows平台是采用下GBK编码规则。
然后再次打开记事本会发现显示的是乱码。因为“连通”的GBK格式编码和UTF-8格式的编码“类型”,所以记事本会用UTF-8的方式进行解码。
采用GBK编码方式的字节码用UTF-8编码方式解码就会出现乱码问题。
输入连通

另存为,修改编码规则为ANSI(GBK)

保存退出,然后再次打开该文本。

我们再次点击另存为:

编码中显示的UTF-8就代表记事本当前的编码规则。
也就是说我们输入“连通”然后用GBK格式保存,记事本自己判断这个编码是UTF-8,然后采用UTF-8方式解码,然后我们看到的就是乱码。
当然这只是个例,换一些别的字符采用上述操作不会出现乱码。
6.4(java学习笔记)转换流的更多相关文章
- java 学习笔记之 流、文件的操作
ava 学习笔记之 流.文件的操作 对于一些基础的知识,这里不再过多的解释, 简单的文件查询过滤操作 package com.wfu.ch08; import java.io.File; import ...
- Java 学习笔记 IO流与File操作
可能你只想简单的使用,暂时不想了解太多的知识,那么请看这里,了解一下如何读文件,写文件 读文件示例代码 File file = new File("D:\\test\\t.txt" ...
- java学习笔记--IO流
第十二章大纲: I/O input/output 输入/输出 一.创建文件,借助File类来实现 file.createNewFile() : 创建文件 file.exists() : 判断文件是否存 ...
- java学习笔记——IO流部分
IO流常用的有:字符流.字节流.缓冲流.序列化.RandomAccessFile类等,以上列出的都是开发中比较常用的. 1.字节流: 字节流包含:FileInputStream/FileOutputS ...
- java学习笔记 --- IO流小结
IO流 |--字节流 |--字节输入流 InputStream int read():一次读取一个字节 int read(byte[] bys):一次读取一个字节数 ...
- java学习笔记16--I/O流和文件
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input Output)流 IO流用来处理 ...
- Java学习笔记六(I/O流)
1.介绍 在实际开发过程中经常会用到数据的输入/输出操作,本篇博客着重分析一下,java中经经常使用到的有关IO操作的类.而在java中能够将经常使用的流分为两个部分:字节流和字符流. 1.流的抽象基 ...
- 《Java学习笔记(第8版)》学习指导
<Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...
- 20145330第六周《Java学习笔记》
20145330第六周<Java学习笔记> . 这周算是很忙碌的一周.因为第六周陆续很多实验都开始进行,开始要准备和预习的科目日渐增多,对Java分配的时间不知不觉就减少了,然而第十和十一 ...
- Java学习笔记4
Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...
随机推荐
- HDU 多校对抗赛第二场 1004 Game
Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- bzoj Gty的超级妹子树 块状树
Gty的超级妹子树 Time Limit: 7 Sec Memory Limit: 32 MBSubmit: 500 Solved: 122[Submit][Status][Discuss] De ...
- PHP设计模式-工厂模式、单例模式、注册模式
本文参考慕课网<大话PHP设计模式>-第五章内容编写,视频路径为:http://www.imooc.com/video/4876 推荐阅读我之前的文章:php的设计模式 三种基本设计模式, ...
- event loop 小记
水平不够,只能整理一下知乎大神的回答,勉强度日这样子 在一个事件循环里,会有两个主要的队列:task queue 和 micro-task quene. 其中 task 包括: script(整体代码 ...
- 转:Mybatis系列之集合映射
转:Mybatis系列之集合映射 上篇文章我们讲了关联映射,实现了销售与登录用户之间的关联.本文我们接着来讲一讲集合映射,实现销售与客户的多对多关系. 实现销售与客户多对多关系 本文中仍延用<M ...
- netty的Udp单播、组播、广播实例+Java的Udp单播、组播、广播实例
网络上缺乏netty的udp的单播.组播案例,经过一番学习总结之后终于把这两个案例调通,下面把这两个案例的代码放在这里分享一下. 首先推荐博文: http://colobu.com/2014/10/2 ...
- MySQL实现分页查询
imit 基本实现方式 一般情况下,客户端通过传递 pageNo(页码).pageSize(每页条数)两个参数去分页查询数据库中的数据,在数据量较小(元组百/千级)时使用 MySQL自带的 limit ...
- #error#学习方法,如何避免初始化错误
#error#学习方法,如何避免初始化错误.错误来自:本博客的另一篇文章Demo示例程序源代码: ,01-导航实例-QQ空间.xcodeproj - CYLLoginViewController.mD ...
- Nginx的主要配置参数说明
#定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数.worker_processes 8; #全局错误日志定义类型,[ debug | in ...
- SpringMvc基础知识(二) springmvc和mybatis整合
1 springmvc和mybatis整合 1.1 需求 使用springmvc和mybatis完成商品列表查询. 1.2 整合思路 springmvc+mybaits的系统架构: 第一步:整合dao ...