代码中涉及到编码格式问题的心得

学习编程两年多一点了,一直以来还是看得多而实际动手少。
近来下定决心自己动手完成两个完整的项目,第一个项目是用java编写一个C♭语言(C语言简化版)的编译器(模仿《自制编译器》的例子),在整个项目编码过程中,我会记录下自己的学习心得。

言归正传,编码问题一直都是编码过程中不可忽视的一环,在我过往的工作和学习也一直不停的和编码格式打交道,自我感觉还是理解得比较透彻。但是在实际项目编码过程中,发现自己对编码格式各种转换的理解还是不够清晰,我的第一篇博客就是记录在查找编码问题的解决方案过程中的一些心得体会。

什么是计算机编码

编码格式本质上就是一张目标语言和计算机二进制存储格式之间的对应关系表。由于目标语言的不同,当前存在着不同的编码格式,其中Unicode的目标就是为所有存在的语言制定一个统一的编码。
早期的编码如ASCII,gb2312等都是长度固定的编码—即目标语言每一个单词对应的二进制存储长度固定(ASCII是一个字节,gb2312是两个字节)。而后来出现编码格式 UTF-8 的编码长度则是可变的。
可变长编码的设计思想和IP地址分类的思想是一致,通过这种方法,在不修改原有编码和单词的对应表的情况下,能很简单的增加编码表示的范围。

哈夫曼压缩 也使用了可变长编码的思想,即将频率较高的单词用较小长度的编码表示,能很好的对文件进行压缩

java编码

java默认是以Unicode编码字符串的。具体是什么意思呢,我们举例说明:

String name = "张三";
byte[] bytes = name.getBytes("gb2312");
name = new String(bytes, "gb2312");

1、字符串name在内存中以Unicode编码的格式进行存储。
2、getBytes函数将字符串name取出,以gb2312重新编码,并将所得编码以byte数组的形式返回。
3、将byte数组传递给String的构造函数,并告诉构造函数,这个byte数组的编码格式是gb2312,之后构造函数将其转换为字符串,并在内存中以Unicode的格式存储。
4、String构造函数的意义在于,java程序读取外部输入时是以字节流的形式读入的,指定了编码格式,就可以转换为java可以识别的形式。

特殊表示

“\345\244\247\345\256\266\345\245\275\343\200\202”
单斜杠+三个数字 这样的表示对于的一个八进制的数字,表示的是一个扩展的ascii编码(即ISO8859-1)
取出后再以utf-8形式编码可得对应的三个汉字 — “大家好”

byte[] bytes = "\345\244\247\345\256\266\345\245\275\343\200\202".getBytes("ISO8859-1");
//  System.out.println(new String(bytes, "utf-8")); 这里可以省略utf-8
System.out.println(new String(bytes);

平台相关性

1、windows中文平台的默认输入是编码格式是gb2312,当java执行windows命令后,获取返回的字节流时,要指定字节流的编码格式gb2312,之后java程序才能正确解析返回值。

static private void passThrough(InputStream stream) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "gb2312"));
        String line;
        while ((line = reader.readLine()) != null){
            System.err.println(line);
        }
    }

2、python执行windows命令也是类似的情况。

res_g = subprocess.check_output('ipconfig')
res = res_g.decode('gbk')
print(res)

文件编码格式与程序编码格式

一般情况下,我们会设置文件的编码格式,那么文件的编码格式和程序的编码格式又是什么关系呢。
比如我们指定python文件编码格式是gb2312,python程序执行时,读取python源文件,载入内存时,解释器将gb2312的编码格式转换成Unicode的格式,在进行执行。
同理,jvm载入字节码时(可能是从文件中获取,也可能是从网络中获取,对jvm来说只要是字节流就可以),需要知道字节码的编码格式,然后转换成java默认的Unicode格式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值