zoukankan      html  css  js  c++  java
  • 3.字符编码

    字符编码

    编者的话:从磁盘中读取数据时,直接将存在文件中的二进制转换成unicode的二进制存到内存中,需指定一个编码如utf-8,前提是文件在存储时是以utf-8存储的.系统中维护了一张关于utf-8到unicode的表,存文件时,直接通过这张表将内存中unicode的二进制翻译成utf-8的二进制写入文件.
    ps.不同的编码如gbk,也有一张类似的表存在.

    一.了解字符编码的知识储备

    文本编辑器存取文件的原理(nodepad++,pycharm,word

    1. 打开编辑器就打开了启动了一个进程,是在内存中的,所以在编辑器编写的内容也都是存放与内存中的,断电后数据丢失,因而需要保存到硬盘上,点击保存按钮,就从内存中把数据刷到了硬盘上。
      在这一点上,我们编写一个py文件(没有执行),跟编写其他文件没有任何区别,都只是在编写一堆字符而已。

    2. python解释器执行py文件的原理,例如pythontest.py

      第一阶段:python解释器启动,此时就相当于启动了一个文本编辑器

      第二阶段:python解释器相当于文本编辑器,去打开test.py文件,从硬盘上将test.py的文件内容读入到内存中
      第三阶段:python解释器解释执行刚刚加载到内存中test.py的代码

    3. 总结:python解释器是解释执行文件内容的,因而python解释器具备读py文件的功能,这一点与文本编辑器一样,与文本编辑器不一样的地方在于,python解释器不仅可以读文件内容,还可以执行文件内容

    二.什么是字符编码

    • 计算机要想工作必须通电,也就是说‘电’驱使计算机干活,而‘电’的特性,就是高低电平(高低平即二进制数1,低电平即二进制数0),也就是说计算机只认识数字

    • 编程的目的是让计算机干活,而编程的结果说白了只是一堆字符,也就是说我们编程最终要实现的是:一堆字符驱动计算机干活

    • 所以必须经过一个过程:
      字符--------(翻译过程)------->数字

      这个过程实际就是一个字符如何对应一个特定数字的标准,这个标准称之为字符编码

    三.字符编码的发展史

    阶段一:现代计算机起源于美国,最早诞生也是基于英文考虑的ASCII

    • ASCII:一个Bytes代表一个字符(英文字符/键盘上的所有其他字符),1Bytes=8bit,8bit可以表示0-2**8-1种变化,即可以表示256个字符
      ASCII最初只用了后七位,127个数字,已经完全能够代表键盘上所有的字符了(英文字符/键盘的所有其他字符)后来为了将拉丁文也编码进了ASCII表,将最高位也占用了

    阶段二:为了满足中文,中国人定制了GBK

    • GBK:2Bytes代表一个字符

      为了满足其他国家,各个国家纷纷定制了自己的编码
      日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里

    阶段三:各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

    • 于是产生了unicode,统一用2Bytes代表一个字符,2**16-1=65535,可代表6万多个字符,因而兼容万国语言,但对于通篇都是英文的文本来说,这种编码方式无疑是多了一倍的存储空间(二进制最终都是以电或者磁的方式存储到存储介质中的,于是产生了UTF-8,对英文字符只用1Bytes表示,对中文字符用3Bytes

    • 需要强调的一点是:

      unicode:简单粗暴,所有字符都是2Bytes,优点是字符->数字的转换速度快,缺点是占用空间大
      utf-8:精准,对不同的字符用不同的长度表示,优点是节省空间,缺点是:字符->数字的转换速度慢,因为每次都需要计算出字符需要多长的Bytes才能够准确表示


    • 内存中使用的编码是unicode,用空间换时间(程序都需要加载到内存才能运行,因而内存应该是尽可能的保证快,硬盘中或者网络传输用utf-8,网络I/O延迟或磁盘I/O延迟要远大与utf-8的转换延迟,而且I/O应该是尽可能地节省带宽,保证数据传输的稳定性。

        所有程序,最终都要加载到内存,程序保存到硬盘不同的国家用不同的编码格式,但是到内存中我们为了兼容万国(计算机可以运行任何国家的程序原因在于此),
        统一且固定使用unicode,这就是为何内存固定用unicode的原因,你可能会说兼容万国我可以用utf-8啊,可以,完全可以正常工作,
        之所以不用肯定是unicode比utf-8更高效啊(uicode固定用2个字节编码,utf-8则需要计算),但是unicode更浪费空间,没错,这就是用空间换时间的一种做法,
        而存放到硬盘,或者网络传输,都需要把unicode转成utf-8,因为数据的传输,追求的是稳定,高效,数据量越小数据传输就越靠谱,于是都转成utf-8格式的,而不是unicode。
      

    分析过程?什么是乱码

    文件从内存刷到硬盘的操作简称存文件

    乱码一:存文件时就已经乱码
    存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存,
    本质上其他国家的文字由于在shiftjis中没有找到对应关系而导致存储失败,用open函数的write可以测试,f=open('a.txt','w',encodig='shift_jis')
    f.write('你瞅啥
    何を見て
    ')#'你瞅啥'因为在shiftjis中没有找到对应关系而无法保存成功,只存'何を見て
    '可以成功
    但当我们用文件编辑器去存的时候,编辑器会帮我们做转换,保证中文也能用shiftjis存储(硬存,必然乱码),这就导致了,存文件阶段就已经发生乱码
    此时当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了
    

    文件从硬盘读到内存的操作简称读文件

    乱码二:存文件时不乱码而读文件时乱码
    存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,读阶段发生乱码是可以解决的,选对正确的解码方式就ok了,而存文件时乱码,则是一种数据的损坏。
    

    分析过程?

    总结:
    无论是何种编辑器,要防止文件出现乱码(请一定注意,存放一段代码的文件也仅仅只是一个普通文件而已,此处指的是文件没有执行前,我们打开文件时出现的乱码)
    核心法则就是,文件以什么编码保存的,就以什么编码方式打开

    5.2程序的执行

    • pythontest.py(我再强调一遍,执行test.py的第一步,一定是先将文件内容读入到内存中)
    • 阶段一:启动python解释器
    • 阶段二:python解释器此时就是一个文本编辑器,负责打开文件test.py,即从硬盘中读取test.py的内容到内存中>此时,python解释器会读取test.py的第一行内容
    • #coding:utf-8,来决定以什么编码格式来读入内存,这一行就是来设定python解释器这个软件的编码使用的编码格式这个编码,
    • 如果不在python文件指定头信息#--coding:utf-8--,那就使用默认的,python2中默认使用ascii,python3中默认使用utf-8
    • 阶段三:读取已经加载到内存的代码(unicode编码的二进制),然后执行,执行过程中可能会开辟新的内存空间,比如x="egon",内存的编码使用unicode,不代表内存中全都是unicode编码的二进制,
      在程序执行之前
    • 内存中确实都是unicode编码的二进制,比如从文件中读取了一行x="egon",其中的x,等号,引号,地位都一样,都是普通字符而已,都是以unicode编码的二进制形式存放与内存中的
    • 但是程序在执行过程中,会申请内存(与程序代码所存在的内存是俩个空间),可以存放任意编码格式的数据,比如x="egon",会被python解释器识别为字符串,会申请内存空间来存放"hello",然后让x指向该内存地址,此时新申请的该内存地址保存也是unicode编码的egon,如果代码换成x="egon".encode('utf-8'),那么新申请的内存空间里存放的就是utf-8编码的字符串egon了
  • 相关阅读:
    angular6跨域问题proxy.conf.json
    angular2 防止刷新页面 参数丢失
    自定义修改table样式 scoped会影响
    angular ngfor和ngif指令共用
    yum 是轮船发动机,brew 是汽车发动机,不能混用。
    Vue watch 监听 computed
    vue 路由跳转,参数消失问题
    vue 使用:class切换高亮 点击路由跳转 上个组件的点击事件保存的参数 在下一次重复进入这个组件的时候 默认值都已经还原了 得通过路由跳转的时候 把上个组件的状态通过路由保存下来 通过下一次进入这个组件的时候 获取路由 渲染当前页面的:class 进行高亮
    函数防抖 函数节流
    vue router-view router-link RouterView【命令视图】和RouterLink【命令路线】本身是两个组件。 命名路由
  • 原文地址:https://www.cnblogs.com/jec1999/p/7051216.html
Copyright © 2011-2022 走看看