一、乱码问题

我们来看下列例子:  

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. 有关spring的各种下载资料的网站

    spring的文件和jar包下载的网站: https://repo.spring.io/release/org/springframework/spring/ spring 各个版本源码下载的资料: ...

  2. org.apache.hadoop.hdfs.server.datanode.DataNode: Exception in receiveBlock for block

    Hbase依赖的datanode日志中如果出现如下报错信息:DataXceiverjava.io.EOFException: INFO org.apache.hadoop.hdfs.server.da ...

  3. 九大排序算法Java实现

    之前学习数据结构与算法时花了三天时间整理九大排序算法,并采用Java语言来实现,今天第一次写博客,刚好可以把这些东西从总结的文档中拿出来与大家分享一下,同时作为自己以后的备忘录. 1.排序算法时间复杂 ...

  4. MySql binlog(理论篇)

    1.什么是binlog? binlog日志用于记录所有更新了数据的sql语句或保存被修改的记录Row: 有了binlog,可以用于实时备份,master/slave主从同步: 在5.0版本前支持文本格 ...

  5. Android 全面插件化 RePlugin 流程与源码解析

    转自 Android 全面插件化 RePlugin 流程与源码解析 RePlugin,360开源的全面插件化框架,按照官网说的,其目的是“尽可能多的让模块变成插件”,并在很稳定的前提下,尽可能像开发普 ...

  6. [bzoj3597][scoi2014]方伯伯运椰子——分数规划,负环

    题解 目标就是 \[Maximize\ \lambda = \frac{X-Y}{k}\] 按照分数规划的一般规律, 构造: \[g(\lambda) = \lambda k + Y - X\] 由于 ...

  7. javascript中实例方法与类方法的区别

    在javascript中,类有静态属性和实例属性之分,也有静态方法和实例方法之分 类属性(静态属性):通过类直接访问,不需要声明类的实例来访问 类方法(静态方法):通过类直接访问,不需要声明类的实例来 ...

  8. python3 闭包函数,装饰器

    闭包函数: 1.定义在函数内部的函数 2.包含对外部作用域而非全局作用域的引用特点: 1.自带作用域 2.延迟计算(取到内存地址,加括号执行) def 外部函数(func): def 内部函数(*ar ...

  9. ANDROID开发笔记(一)

    manifest, 英['mænɪfest] vt. 显示,表明;证明;使显现 adj. 明白的,明显的 n. 货单,旅客名单 wrap_content, 根据实际内容调整   原来新版的ADB已经支 ...

  10. [Leetcode Week8]Triangle

    Triangle 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/triangle/description/ Description Given a t ...