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

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

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

String 从哪里来?

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

String 的构造函数

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

public String(char value[]) {}

继续阅读

文本在内存中的字符集编码(1)--String 的本质--乱码探源(4)

摘要: 文本在内存中的编码以及 String 类型的本质.

让我们从一个故事开始说起. 话说北大是很有哲学传统的, 当你准备踏进北大校门时, 连门卫都会连问你三个终极哲学问题:

你是谁? 你从哪里来? 你要到哪里去?

那么这与我们的问题又有何关系呢? 我觉得理解内存中的编码的关键在于理解 String 类型, 因此我们也来探讨一下 String 的前世今生:

  • String 是谁(什么)?
  • String 从哪里来?
  • String 到哪里去?

当我们能够清晰地回答这三个终极问题时, 对文本在内存中的编码也算理解得差不多了.

注: 文中将用 Java 平台为例来探讨这些问题.

继续阅读

引入字符集编码信息的一些实践--乱码探源(3)

摘要: 介绍了两种引入编码信息的实践, 变相引入及外部指定.

前面说到, 文本文件中没有编码信息, 导致了各种混乱, 那么, 最关键的就是要指定好所用的编码信息. 具体地讲, 有以下一些途径.

变相引入

什么是变相引入呢? 其实本质与前面提到的一些"文件头"信息是类似的.

xml

我们来看看 xml 文件的例子, 你通常能在最开始看到这样的一行:

<?xml version="1.0" encoding="UTF-8"?>

那么这里面, encoding 指明的就是所用编码的信息了. 可是, 等等!! 为了得到这一编码信息, 我得先读取这一文件;可要正确读取文件, 我又要先知道编码信息!

这成了一个鸡生蛋, 蛋生鸡, 又或者说是先有鸡还是先有蛋的问题了.

怎么破呢? 考虑这一行信息所有字符都是 ASCII 中的字符, 那么我们可以先使用最基础的 ASCII 去读取它开头的一些信息, 获取到这一编码信息后, 再次用这一编码去读取文件即可.

ASCII 可谓是这样一个始祖鸟或者始祖蛋一样的存在.

可以动动手做些实验, 先建立一个 xml 文件, 比如就叫 foo.xml

foo.xml

继续阅读

确定文本文件的字符集编码--乱码探源(2)

摘要: 介绍了如何去确定一个文本文件所使用的编码, 特别地以记事本保存"联通"为例进行了深入分析.

在上一篇中, 探讨了文件名编码以及非文本文件中的文本内容的编码, 在这里, 将介绍更为重要的文本文件的编码.

混乱的现状

设想一下, 如果在保存文本文件时, 也同时把所使用的编码的信息也保存在文件内容里, 那么, 在再次读取时, 确定所使用的编码就容易多了.

很多的非文本文件比如图片文件通常会在文件的头部加上所谓的 "magic number(魔法数字)" 来作为一种标识.

所谓的 "magic number", 其实它就是一个或几个固定的字节构成的固定值, 用于标识文件的种类(类似于签名).

比如 bmp 文件通常会以 "42 4D" 两字节开头.

又比如 Java 的 class 文件, 则是以四字节的 "ca fe ba be" 打头. (咖啡宝贝? )

java class magic number

即便没有文件后缀名, 根据这些信息也是确定一个文件类型的手段.

附: 关于用 Notepad++ 查看十六进制的问题, 这是一个插件, 如果没有装, 菜单--插件--plugin manager--available--HEX-Editor, 装上它.

装上后, 它通常在工具栏的最右边, 一个黑色的大写的斜体的"H"就是它. 单击它可以在正常文本与 16 进制间切换. 要进一步查看二进制, 在文本区, 右键--view in--to binary.

继续阅读

文件, 文本文件以及编码--乱码探源(1)

摘要: 介绍了文件名在操作系统中的编码, 以及一些非文本文件中的文本内容所用的编码.

在前面的字符集编码系列中, 已经探讨了几大主要的字符集编码. 在此基础之上, 这里将进一步探讨编码的应用及乱码的根源, 我们先从基本的文件说起.

文件

文件(内容)就是字节序列. 文本文件也是文件, 所以它也是字节序列.

文件名与文件内容

通常说到文件时, 指的是 文件内容, 但文件还有 文件名, 文件名与文件内容是分开存储的. 你可以在硬盘上新建一个文件, 它的大小为 0. 如下:

大小为0的新建文本文档

但它是有文件名的, 比如上述的"新建文本文档.txt", 保存这些名字自然也要占用空间, 只不过它与文件内容是分离的.

这些由操作系统的文件系统模块负责.

继续阅读