一、乱码问题

我们来看下列例子:  

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学习笔记)转换流的更多相关文章

  1. java 学习笔记之 流、文件的操作

    ava 学习笔记之 流.文件的操作 对于一些基础的知识,这里不再过多的解释, 简单的文件查询过滤操作 package com.wfu.ch08; import java.io.File; import ...

  2. Java 学习笔记 IO流与File操作

    可能你只想简单的使用,暂时不想了解太多的知识,那么请看这里,了解一下如何读文件,写文件 读文件示例代码 File file = new File("D:\\test\\t.txt" ...

  3. java学习笔记--IO流

    第十二章大纲: I/O input/output 输入/输出 一.创建文件,借助File类来实现 file.createNewFile() : 创建文件 file.exists() : 判断文件是否存 ...

  4. java学习笔记——IO流部分

    IO流常用的有:字符流.字节流.缓冲流.序列化.RandomAccessFile类等,以上列出的都是开发中比较常用的. 1.字节流: 字节流包含:FileInputStream/FileOutputS ...

  5. java学习笔记 --- IO流小结

    IO流  |--字节流    |--字节输入流     InputStream      int read():一次读取一个字节      int read(byte[] bys):一次读取一个字节数 ...

  6. java学习笔记16--I/O流和文件

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note16.html,转载请注明源地址. IO(Input  Output)流 IO流用来处理 ...

  7. Java学习笔记六(I/O流)

    1.介绍 在实际开发过程中经常会用到数据的输入/输出操作,本篇博客着重分析一下,java中经经常使用到的有关IO操作的类.而在java中能够将经常使用的流分为两个部分:字节流和字符流. 1.流的抽象基 ...

  8. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  9. 20145330第六周《Java学习笔记》

    20145330第六周<Java学习笔记> . 这周算是很忙碌的一周.因为第六周陆续很多实验都开始进行,开始要准备和预习的科目日渐增多,对Java分配的时间不知不觉就减少了,然而第十和十一 ...

  10. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

随机推荐

  1. POJ2492:A Bug's Life(种类并查集)

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 45757   Accepted: 14757 题 ...

  2. 安卓sdk安装教程

    http://blog.csdn.net/love4399/article/details/77164500

  3. Windows下安装Mycat-web

    Mycat-web是基于Mycat的一个性能监控工具,如:sql性能监控等. 在安装Mycat-web之前需要先安装Zookeeper: 可参考: http://blog.csdn.net/tlk20 ...

  4. Java中一些知识的归纳总结

    1.包装类型与基本数据类型的区别. Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这使得Java在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据 ...

  5. Hackerrank [World CodeSprint 11] City Construction

    传送门:https://www.hackerrank.com/contests/world-codesprint-11/challenges/hackerland [题解] 因为加点每次加1个点1条边 ...

  6. Python爬虫学习 - day2 - 站点登陆

    利用Python完成简单的站点登陆 最近学习到了爬虫,瞬时觉得很高大上,想取什么就取什么,感觉要上天.这里分享一个简单的登陆抽屉新热榜的教程(因为它不需要验证码,目前还没有学会图像识别.哈哈),供大家 ...

  7. Makefile 的 prequisite 執行順序 single multi thread

    Makefile 代碼如下: B 需要 A 的 產出, all: A B A B 是 target, case 1: single-thread make -j1 則執行的順序為 A -> B ...

  8. 4.shell预定义变量

    就是shell设计者实现预定好的变量,可以直接在shell脚本中使用$$:当前进程的进程号(pid)$!:后台运行的最后一个进程的进程号(pid)$?:最后一次执行的命令的返回状态,如果这个变量的值为 ...

  9. wxBot微信机器人框架(转)

    原文:http://blog.csdn.net/tobacco5648/article/details/50722321 wxBot 是Python包装Web微信实现的微信机器人框架.可以很容易地实现 ...

  10. IOC(控制反转)的理解

    1.IOC的理论背景 我们知道在面向对象设计的软件系统中,它的底层都是由N个对象构成的,各个对象之间通过相互合作,最终实现系统地业务逻辑[1]. 图1 软件系统中耦合的对象 如果我们打开机械式手表的后 ...