快捷搜索:  汽车  科技

java编码规则及原则:一次搞懂Java中的编码问题

java编码规则及原则:一次搞懂Java中的编码问题能表示汉字的有GB2312、GBK、UTF-8、UTF-16 这几种。不同的编码格式在存储空间和编码效率方面都有不同。现在的编码格式有很多,常见的有 ASCII、ISO-8859-1、GB2312、GBK、UTF-8、UTF-16 等。2,人类语言的符号太多,255位不够3,所以必须把多个字节合起来表示一个人类语言符号4,在怎么组合字节上出现了多种方法,这就是编码

编码问题一直是一个困扰程序员的问题,尤其是对于Java程序员。因为java的跨平台特性,经常需要在多个编码之间进行转换。

下面详细讲一讲java中的编码问题

一、为什么要编码

长话短说,原因如下:

1,计算机存储信息的最小单位是字节byte。占8个二进制位。所以一个字节能表示的状态只有255中

2,人类语言的符号太多,255位不够

3,所以必须把多个字节合起来表示一个人类语言符号

4,在怎么组合字节上出现了多种方法,这就是编码

二、常用编码格式

现在的编码格式有很多,常见的有 ASCII、ISO-8859-1、GB2312、GBK、UTF-8、UTF-16 等。

能表示汉字的有GB2312、GBK、UTF-8、UTF-16 这几种。不同的编码格式在存储空间和编码效率方面都有不同。

如何选择,需要多方考虑。

先简单介绍一下这几种编码。

ASCII 码

最基础的编码格式,标准ASCII码只有127个。连一个字节都没用完,只用了低7位。

后来又除了扩展ASCII码把第8位利用了起来。不过总的来说,能表示的字符非常有限。

Reader 类是 Java 的 I/O 中读字符的父类,而 InputStream 类是读字节的父类,InputStreamReader 类就是关联字节到字符的桥梁,它负责在 I/O 过程中处理读取字节到字符的转换,而具体字节到字符的解码实现它由 StreamDecoder 去实现,在 StreamDecoder 解码过程中必须由用户指定 Charset 编码格式。值得注意的是如果你没有指定 Charset,将使用本地环境中的默认字符集,例如在中文环境中将使用 GBK 编码。

写的情况也是类似,写字符的父类是 Writer,写字节的父类是 OutputStream,通过 OutputStreamWriter 转换字符到字节。如下图所示:

java编码规则及原则:一次搞懂Java中的编码问题(1)

同样 StreamEncoder 类负责将字符编码成字节,编码格式和默认编码规则与解码是一致的。

写个代码测试一下:

public class IOTest { @Test public void testWrite() throws Exception { String file = "d:/test1.txt"; String charset = "UTF-8"; // 写字符换转成字节流 FileOutputStream outputStream = new FileOutputStream(file); OutputStreamWriter writer = new OutputStreamWriter( outputStream charset); try { writer.write("保存点中文字符"); } finally { writer.close(); } } @Test public void testRead() throws Exception { String file = "d:/test1.txt"; String charset = "UTF-8"; // 读取字节转换成字符 FileInputStream inputStream = new FileInputStream(file); InputStreamReader reader = new InputStreamReader( inputStream charset); StringBuffer buffer = new StringBuffer(); char[] buf = new char[64]; int count = 0; try { while ((count = reader.read(buf)) != -1) { buffer.append(buf 0 count); } } finally { reader.close(); } System.out.println(buffer.toString()); } }

你可以改下字符集,多测几次。读写使用不同的字符集会乱码。

我们在写代码的时候,一定要手动指定下字符集,不要使用默认。虽然在一台机器上,不会出问题。一旦涉及到跨机器可能有异常。

我们可以看下默认的字符集到底是啥。

这是jdk的源码。在vm启动时,找有没有配file.encoding参数,配了,去找对应的字符集。如果字符集比较特殊,在不同的机器上有可能找不到的。否则就是UTF-8

/**

* Returns the default charset of this Java virtual machine.

*

* <p> The default charset is determined during virtual-machine startup and

* typically depends upon the locale and charset of the underlying

* operating system.

*

* @return A charset object for the default charset

*

* @since 1.5

*/

public static Charset defaultCharset() {

if (defaultCharset == null) {

synchronized (Charset.class) {

String csn = AccessController.doPrivileged(

new GetPropertyAction("file.encoding"));

Charset cs = lookup(csn);

if (cs != null)

defaultCharset = cs;

else

defaultCharset = forName("UTF-8");

}

}

return defaultCharset;

}

java代码中的编解码

除了io之外,我们也经常在代码中进行string和byte的转换。

String s = "中文字符串";

byte[] b = s.getBytes("UTF-8");

String n = new String(b "UTF-8");

随手指定字符集是个好习惯

猜您喜欢: