zoukankan      html  css  js  c++  java
  • 字符编码与文件操作

    字符编码

    计算机基础

    数据存放在硬盘,

    双击应用程序的快捷键--》把应用程序的硬盘所在的路径给操作系统--》操作系统把这个指令转换成机器语言给CPU-->CPU告诉内存去硬盘取应用程序的代码--》应用程序代码读入内存--》应用程序启动

    打开文本编辑器就是上述的一个过程

    py文件已经读入内存,python解释器执行.py的代码的过程:

    解释python语法,然后才有了变量的概念

    字符编码

    a = 1
    

    'a' , '=','1'这三个字符在硬盘里是0和1的形式。

    文本编译器的翻译是把 'a = 1'的二进制翻译成 a = 1,这个过程就叫字符编码。

    涉及到字符编码的两个场景

    • 1.一个Python文件中的内容是由一堆字符组成的,存取均涉及到字符编码问题(Python文件并未执行,前两个阶段均属于该范畴)。
    • 2.Python中的数据类型字符串是由一串字符组成的(Python文件执行时,即第三个阶段)。

    统一万国字符的 Unicode

    • 1.Unicode存没有任何问题,但是英文2个字节就够用了,还用4个字节存储了,浪费空间然后定制了一套和unicode对应的编码,即utf8,所以存储的时候用utf8
    • 2.utf8只和unicode有对应关系,所以内存中用utf8的话,就会不认识acill、gbk、shift编码,所以utf8不能放在内存

    乱码分析

    • 1.乱码一:存文件时就已经乱码
      存文件时,由于文件内有各个国家的文字,我们单以shiftjis去存,
      本质上其他国家的文字由于在shiftjis中没有找到对应关系而导致存储失败。但当我们硬要存的时候,编辑并不会报错(难道你的编码错误,编辑器这个软件就跟着崩溃了吗???),但毫无疑问,不能存而硬存,肯定是乱存了,即存文件阶段就已经发生乱码,而当我们用shiftjis打开文件时,日文可以正常显示,而中文则乱码了。
    • 2.乱码二:存文件时不乱码而读文件时乱码
      存文件时用utf-8编码,保证兼容万国,不会乱码,而读文件时选择了错误的解码方式,比如gbk,则在读阶段发生乱码,读阶段发生乱码是可以解决的,选对正确的解码方式就ok了。

    总结

    • 1.以后写代码的时候记住:用什么编码格式写代码,就用什么编码格式读取代码。
    • 2.Unicode----->encode(编码)-------->gbk # 从内存到硬盘
    • 3.Unicode<--------decode(解码)<----------gbk # 从硬盘到内存

    文件操作

    什么是文件?

    文件是操作系统为用户或应用程序提供的一个读写硬盘的虚拟单位。文件的操作是基于文件,即文件的操作核心就是:读和写。
    也就是只要我们想要操作文件就是对操作系统发起请求,然后由操作系统将用户或应用程序对文件的读写操作转换成集体的硬盘指令(比如控制盘片转动,控制机械手臂移动,以此来读取数据)。
    操作系统,windows操作系统有应用程序,linux操作系统也有应用程序(Linux一切皆文件)。

    为什么要有文件?

    内存无法永久保存数据,我们想要永久保存数据都需要把文件保存到硬盘中,我们不能直接操纵硬件,而操作文件就可以实现对硬件的操作。

    如何用文件?

    当我们需要打开文件,我们双击文件,对操作系统发送打开指令,在Python中,我们也有类似双击的命令. open可以打开文件,但是我们可以 read ,write ,append文件,注意模式,同时打开文件后关闭。

    fr = open(r'E:孔	est1', mode='r', encoding='utf8')
    print(fr)
    print(fr.read())
    # print(f.write('aaa'))  报错
    fr.close()
    
    fw = open(r'E:孔	est2', mode='w', encoding='utf8')  # 会先清空文件在写入,append追加
    print(fw)
    fw.write('你好世界!')
    fw.flush()  # 快速刷新
    
    <_io.TextIOWrapper name='E:\孔\test\1' mode='r' encoding='utf8'>
    Hello world!!
    <_io.TextIOWrapper name='E:\孔\test\2' mode='w' encoding='utf8'>
    

    绝对路径与相对路径

    绝对路径从根目录开始

    相对路径从当前文件目录开始

    文件读写内容的格式有两种(默认的读写内容的模式为b模式):

    • t模式: text
    • b模式: bites
    with open(r'E:孔	est1', 'rb') as fr:  # with open 打开文件后,会自己关闭文件
        print(fr)
        print(fr.read())
    with open(r'E:孔	est1', 'rt') as fr:
        print(fr)
        print(fr.read())
    
    <_io.BufferedReader name='E:\孔\test\1'>
    b'Hello world!!'
    <_io.TextIOWrapper name='E:\孔\test\1' mode='rt' encoding='cp936'>
    Hello world!!
    
    # 执行复制功能
    with open(r'E:孔	est1', 'r', encoding='utf8') as fr,
            open(r'E:孔	est2', 'w', encoding='utf8') as fw:
        data = fr.read()
        fw.write(data)
    

    修改文件内容的两种方式

    文件的数据是存放于硬盘上的,因而只存在覆盖,不存在修改这一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式。

    方式一:一次性读所有

    将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,在由内存覆盖到硬盘(Word,vim,nodpad++等编辑器)。

    import os
    
    with open(r'E:孔	est1.txt', 'r', encoding='utf8') as fr,
            open(r'E:孔	est1_swap.txt', 'w', encoding='utf8') as fw:
        data = fr.read()  # 全部读入内存,如果文件很大,会很卡
        data = data.replace('tom', 'tom and jerry')  # 在内存中完成修改
    
        fw.write(data)  # 新文件一次性写入文件内容
    
    # 删除原文件
    os.remove('E:孔	est1.txt')
    # 重命名新文件名为原文件名
    os.rename('E:孔	est1_swap.txt', 'E:孔	est1.txt')
    

    方式二:逐行读取

    将硬盘存放的该文件一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖原文件。

    import os
    with open(r'E:孔	est1.txt', 'r', encoding='utf8') as fr,
            open(r'E:孔	est1_swap.txt', 'w', encoding='utf8') as fw:
        #
        for line in fr:
            line = line.replace('tom and jerry','tom')
            #
            fw.write(line)
            
    os.remove('E:孔	est1.txt')
    os.rename('E:孔	est1_swap.txt','E:孔	est1.txt')
    

    总而言之,修改文件内容的思路为:以读的方式打开原文件,以写的方式打开新文件,把原文件的内容进行修改,然后写入新文件,之后利用os模块的方法,把原文件删除,重命名新文件为原文件名,达到以假乱真的目的

  • 相关阅读:
    JavaScript快速入门-DOM对象
    JavaScript快速入门-ECMAScript对象介绍
    JavaScript快速入门-ECMAScript函数
    JavaScript快速入门-ECMAScript运算符
    [转] boost::function用法详解
    [转] [翻译]图解boost::bind
    [转] Git 分支
    [转] 多线程下变量-gcc原子操作 __sync_fetch_and_add等
    [转] Boost智能指针——scoped_ptr
    [转] linux下的c/c++调试器gdb
  • 原文地址:https://www.cnblogs.com/WilliamKong94/p/10852840.html
Copyright © 2011-2022 走看看