Java 字节流与字符流的字符集编码及乱码(4)--字符

怎样算是"一个字符"?

在这一篇, 我们谈论最后一个话题, 就是"到底怎样才算一个‘字符’"?

其实这个话题在 字符集与编码(五)--代码单元及 length 方法 中和 文本在内存中的编码(1)--乱码探源(4) 也有所涉及, 这里结合字符流的话题再综合深入探讨它一下, 并且还将涉及一个 unicode 组合字符及正规化的话题. (这在前面也没有涉及过的)

怎样算是一个字符?

初看起来, 这是个很 naive 的问题. 以前面经常举的例子来说:

"h" 是一个字符;

"i" 是一个字符;

"你" 是一个字符;

"好" 也是一个字符.

继续阅读

Java 字节流与字符流的字符集编码及乱码(3)--缺省编码

在上一篇中比较了使用字节流和字符流来读取(写入)文本文件的优劣后, 这一篇主要探讨缺省编码这个主题.

字符流使用缺省编码

通过前面的例子, 已经得出了一个结论: 字符流=字节流+编码.

可以在构建字符流时显示传入编码参数, 那么所得到的字符流就会以该编码来**编码(encode)解码(decode)**字节流, 这会给文本数据处理带来极大方便.

但有时, 构建字符流时也可以不传入编码参数, 比如如下直接构建一个 InputStreamReader :

继续阅读

Java 字节流与字符流的字符集编码及乱码(2)--读取文件

在上一篇中介绍了字节流与字符流的关系, 这一篇主要给出一些具体的代码示例.

使用字节流读取文本文件

上篇中说到, 无论是字符流还是字节流, 都可以用于读取文本文件, 特别是对于一整个文件的读取, 两者的差别并不大. 来看一个具体的示例, 假如有如下 gbk 编码的 txt 文件一枚, 具体内容为"hi你好", 对应二进制如下:

gbk 编码 hi你好

那么可以这样去读取:

继续阅读

Java 字节流与字符流的字符集编码及乱码(1)--对比

Java 的 IO 系统是比较庞杂的, 各种流特别多, 其中有一种就是字符流.

在本系列前面的一些文章中, 也曾涉及过字符流的话题, 不过没有详细展开讨论, 这次准备具体综合地谈一谈.

在层次方面的对比

你可能听过不少关于字节流与字符流对比的介绍, 不过严格地说, 我认为把"字节流"和"字符流"去对比这种说法不是特别妥当, 为什么呢?

首先, 这两种流实际上处在不同的层次, 字节流是基础, 而字符流是构建在其上的:

字节流 字符流 层级关系

对于不同层次上的事物, 我认为用"对比"这个词是不太恰当的.

继续阅读

文本在内存中的字符集编码(2)--String 的构造--乱码探源(5)

摘要: 深入探讨了 String 的构造, 编码间的转换以及字节流, 字符流等.

在前面我们探讨了 String 是什么的问题, 现在来看 String 从哪来的问题.

String 从哪里来?

所谓从哪里来也可以看作是 String 的构造问题, 因此我们会从 String 的构造函数说起.

String 的构造函数

在前面我们知道 String 的内部就是 char[], 因此它可以根据一组 char[] 来构建, String 中有这样的构造函数:

public String(char value[]) {}

继续阅读