python字符编码 文件操作

字符编码

1、储备知识

运行python程序的三个步骤:python.py
    1、先启动python解释器
    2、解释器会将文本文件a.py内容由硬盘读入内存
    3、解释器会解释执行刚刚读入内存的内容,识别python语法

2、什么是字符编码

人类的字符 ----- 编码 -----> 数字

  人类的字符 <----- 解码 ----- 数字

  编码与解码的过程必须参照字符编码表

3、为何要学习字符编码

 为了解决运行python程序三个阶段中2、3阶段有可能出现的乱码问题

4、字符编码表发展史

一家独大:
    ASCII:只能识别英文字符
    8bit 对应一个英文字符   1byte = 8bit (byte:字节  bit:(二进制)位,比特)

    
天下大乱
    GBK:能识别汉子与英文
         用2Bytes对应一个字符
    Shift-JIS:日文与英文
    Euc -KR:韩文与英文

  英文字符----->内存:ASCII格式的二进制----->硬盘:ASCII格式的二进制
    中文字符、英文字符----->内存:gbk格式的二进制----->硬盘:gbk格式的二进制
    日文字符、英文字符----->内存:shift-JIS格式的二进制----->硬盘:shift-JIS格式的二进制
    万国字符----->内存:unicode格式的二进制----->硬盘:utf-8格式的二进制

    
分久必合
    unicode:1、万国字符
             2、兼容老的字符编码表

5、结论

如何保证不乱码
    1、编码与解码必须参照同一张字符编码表

文件操作

文件处理

1、什么是文件

文件时操作系统提供给用户或者应用程序操作硬盘的一种机制

python中文件是对象

Linux文件:一切设备都可以看成是文件

文件的作用:把一些数据以文件的形式存储起来,文件由文件系统进行管理,当程序下一次执行的时候,通过文件系统快速找到对应的文件,而找到对应的数据,省时省力。

2、为何要用文件

读写文件 ---> 存取硬盘

应用程序:  open()

操作系统:  打开文件

计算机硬件:  硬盘空间

3、如何用文件

打开文件的两种方式
方式一  open
# encoding指定字符编码表
f = open(r'a\a.txt',mode ='rt',encoding='utf-8')
# f的值 ---> 文件句柄,文件对象
res = f.read()
print(res)
f.close()   # 回收操作系统的资源
方式二  with open
with open(r'a\a.txt',mode = 'rt',encoding = 'utf-8') as f:
    res = f.read()
print(res)
读\写
要了解文件读写模式,需要了解几种模式的区别,以及对应指针

1、控制读写操作模式
    r: 读取文件,文件存在的时候,文件指针调到文件开头,若文件不存在则会报错 ----->默认
    w:写入文件,在文件存在的时候会清空文件,文件指针调到文件开头,若文件不存在则会先创建再写入,会覆盖源文件
    a:写入文件,在文件存在的时候不会清空文件,文件指针调到文件末尾,若文件不存在则会先创建再写入,但不会覆盖源文件,而是追加在文件末尾

2、控制读写内容模式
    t:读写都是文本格式,即读写都是字符串 ----->默认
    b:读写都是bytes格式,bytes等同于二进制
    强调:如果是 t 模式,一定记住加上encoding = '编码格式'
    如果是 b 模式。一定记住别加encoding = '编码格式'

3、 +
    r+:可读可写,文件不存在也会报错,写操作是会覆盖
    w+:可读,可写,文件不存在先创建,会覆盖
    a+:可读,可写,文件不存在先创建,不会覆盖,追加在末尾

注意:这里的覆盖是指每次重新打开文件进行操作是覆盖原来的,如果实在打开文件中则不会覆盖
关闭文件
文件关闭的原因:

*将写缓存同步到磁盘
*Linux系统中每一个进程打开文件的个数是有限的,如果打开文件数到了系统限制,则会打开失败。

文件处理的打开模式

1、控制读写操作的模式

r:只读  w:只写  a:只追加

2、控制文件读写内容的模式

 t:读写的内容都是字符串类型
    特点:1、只适用于文本文件
       2、必须要指定encoding参数

  b:控制读写的内存都是bytes类型
    特点:
       2、一定不要指定encoding参数
r:如果文件不存在则报错,文件存在则将文件指针跳到整个文件的开头

with open(r'b.txt','rt',encoding = 'utf-8') as f:
        res = f.read()
w:如果文件不存在则创建空文档,如果文件存在则清空,文件指针跳到文件开头

  打开了文件不关闭的情况下,新写入的内容永远跟在老内容后面
    
with open(r'b.txt',mode = 'wt',encoding = 'utf-8') as f:
        f.write('123\n')
        f.write('123\n')
        f.write('123\n')
a:如果文件不存在则创建文件,如果文件存在则追加写,文件指针调到文件末尾

  打开了文件不关闭的情况下,新写入的内容永远跟在老内容后面
    
with open(r'b.txt',mode = 'at',encoding = 'utf-8') as f:
        f.write('123\n')
        f.write('123\n')
        f.write('123\n'

3、读写模式

"""
r+t       w+t        a+t
"""

f = open(r'b.txt',mode = 'r+t',encoding = 'utf-8')
print(f.readable())   # True
print(f.writable())   # True
f.close()
"""
b模式
一定不要指定encoding参数
"""


with open('b.txt',mode = 'rb',encoding = 'utf-8') as f:
        pass
ValueError: binary mode doesn't take an encoding argument

with open('b.txt',mode = 'rb') as f:
        res = f.read()
        print(type(res))    # <class 'bytes'>
        print(res)          # b'123\r\n123\r\n123\r\n'
        print(res.decode('utf-8'))
>>>:
123
123
123

4、文件操作方法

文件的读取
read(size)  作用:读取文件(读取size个字节,默认读取全部)
# 只有t模式下的read(n)代表的是字符个数,除此以外都是字节个数

readlines(size)  作用:读取文件返回每一行所组成的列表(读取size行,默认读取全部)

readline()  作用:读取一行

with open(r'a.txt',mode='rt',encoding = 'utf-8') as f:
        res = f.read()
        print(res)
        print('==========')
        res = f.read()
        print(res)

with open(r'a.txt',mode='rt',encoding = 'utf-8') as f:
        print(f.readline())
        print(f.readline())

with open(r'a.txt',mode='rt',encoding = 'utf-8') as f:
        print(f.readlines())
# ['123\n', '123\n', '123\n', 'egon\n', 'egon  123\n', '123']


# a.txt内容:hello你好啊
with open(r'a.txt',mode='rt',encoding = 'utf-8') as f:
    print(f.read(6))   # hello你

with open(r'a.txt',mode='rb') as f:
    print(f.read(6))   # b'hello\xe4'


# 截断文件内容
with open(r'a.txt',mode='a',encoding = 'utf-8') as f:
    f.truncate(6)     # hello� 
文件的写入
with open(r'a.txt',mode='wt',encoding = 'utf-8') as f:
        lines = ['aaa\n','bbb\n','ccc\n']
        # for line in lines:
        #         f.write(line)
        f.writelines(lines)

with open(r'a.txt',mode='wt',encoding = 'utf-8') as f:
        f.write('hello')
        # f.flush()    # 降低效率

5、控制文件指针移动

f.seek(移动的字节个数,模式)

模式有三种:
    0:永远参照文件开头
    1:参照当前所在的位置
    2:永远参照文件末尾

注意:
    只有0模式可以在 t 下使用
    1 和 2 只能在 b 模式下使用
# a.txt内容:hello你好啊with open(r'a.txt',mode='rt',encoding = 'utf-8') as f:
    f.seek(3,0)
    print(f.tell())  # 距离文件开头有多少个字节

with open(r'a.txt',mode='rb') as f:
    f.seek(3,1)
    f.seek(5,1)
    print(f.tell())   # 8
    res = f.read()
    print(res.decode('utf-8'))   # 好啊

with open(r'a.txt',mode='rb') as f:
    f.seek(-3,2)
    print(f.tell())     # 11
    res = f.read()
    print(res.decode('utf-8'))   #

# 指针跳到文件末尾
with open(r'a.txt',mode='rb') as f:
    f.seek(0,2)
指针跳到文件末尾的两种方式
"""方式一"""
with open(r'a.txt',mode='rb') as f:
    f.seek(0,2)
    
"""
方式二
a:如果文件不存在则创建文件,如果文件存在则追加写,文件指针调到文件末尾
打开了文件不关闭的情况下,新写入的内容永远跟在老内容后面
"""
with open(r'a.txt',mode='at',encoding='utf-8') as f:
    f.write('123\n')

6、文件的修改

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

方式一
1、以r模式打开源文件,将源文件内容全部读入内存

2、然后在内存中修改完毕

3、以w模式打开源文件,将修改后的内容写入源文件
  耗费内存不耗费硬盘
with open('a.txt',mode = 'rt',encoding = 'utf-8') as src_f:
    data = src_f.read()
    res = data.replace('liu','egno')

with open('a.txt',mode = 'wt',encoding = 'utf-8') as dst_f:
    dst_f.write(res)
方式二
1、以r模式打开源文件,然后以w模式打开一个临时文件

2、从源文件中读一行到内存中,修改完毕后直接写入临时文件,往复循环,直到操作完所有行

3、删除源文件,将临时文件名改名为源文件
  耗费硬盘不耗费内存
import os

with open('b.txt',mode = 'rt',encoding = 'utf-8') as src_f,\
    open('.b.txt.sap',mode = 'wt',encoding = 'utf-8') as dst_f:
    
    for line in src_f:
        dst_f.write(line.replace('egno','liu'))

os.remove('b.txt')
os.rename('.b.txt.swp','b.txt')

 

posted @ 2021-06-09 16:22  Palpitate~  阅读(50)  评论(0编辑  收藏  举报