一、上周内容回顾
''' 1024Bytes = 1KB 1024KB = 1MB 1024MB = 1GB 1024GB = 1TB 1024TB = 1PB 字符编码表 ASCII码:只有英文字母和符号与数字的对应关系,用8位二进制(1bytes)表示一个英文字符 GBK:中文 英文 符号与数字对应关系,用2bytes表示一个中文符号 兼容英文字符 乱码: 编码与解码不一致 内存中unicode >>>编码(encode) 硬盘中utf-8编码 硬盘中utf-8编码 >>>解码(decode) 内存中的unicode 现在的计算机内存中统一用的都是unicode unicode两大特点: 1.用户无论输入哪个国家的字符都能够正常显示(兼容万国) 2.与任意国家的编码都有对应关系 文件头 # coding:gbk 指定python解释器读取该文件使用gbk编码,而不再用默认的 python2在读取文件默认使用的是ASCII码 python3在读取文件默认使用的是utf-8码 python2 如果不指定文件头 中文没法存储 那是因为python2解释器识别语法存储数据的时候默认使用的是ASCII 如果指定了文件头 python2解释器识别语法存储数据的时候使用文件头指定的编码 python2中通常都会在中文的字符串前面加一个u x = u'上' 告诉python2解释器将上存成unicode的形式 python3 里面的字符串直接存成unicode(******) 保证不乱码的核心: 当初以什么编码存的(encode) 就以什么编码取(decode) x = '上' # 第一种转换方式 res1 = bytes(x,encoding='utf-8') print(res1,type(res1)) res2 = str(res1,encoding='utf-8') print(res2,type(res2)) # 第二种转换方式 res = x.encode('utf-8') print(type(res)) print(res.decode('utf-8')) 文件处理 一套完整的计算机系统 应用程序 操作系统 计算机硬件 什么是文件 操作系统暴露给用户操作复杂硬盘的简易接口 python代码操作文件 f = open(文件路径,mode='读写模式',encoding='utf-8') f.close() (f:遥控器 文件句柄) print(f) 文件的上下文管理 with open(....) as f: 文件操作 文件路径 相对路径:必须有一个参照物 通常是相对于执行文件所在的文件夹 绝对路径:类似于GPS全球定位,不需要有任何的参照物 r用来取消转义 r'D:av ttxxxooo rr' mode不写默认用的是rt encoding参数只在mode位文本模式的情况下才加 文件读写模式 r:只读模式 1.文件不存在的情况下 直接报错 2.文件存在的情况下 光标在文件开头 w:只写模式 1.文件不存在的情况下 自动创建新文件 2.文件存在的情况下 先清空文件内容再执行写入 a:只追加模式(只能在文件末尾添加内容) 1.文件不存在的情况下 自动创建新文件 2.文件存在的情况下 光标直接在文件末尾 文件操作单位 t:文本模式 只能和r/w/a连用 并且不写的情况下 默认就是t b:原生的二进制数据 只能和r/w/a连用 该模式通常用来处理非文本文件 直接存储网络上传输过来的二进制数据 f.read() 一次性将文件内容全部读到内存 当文件过大的情况下该方法可能会导致内存溢出 f.readline():一行行的读取内容 文件句柄f可以直接被for循环 每次for循环拿出来的就是文件一行行的内容 for line in f: print(line) :换行符 现在做了优化 可以只写 或者 f.readlines():将文件一行行的内存放是列表中 成为一个个元素 f.readable():是否可读 f.write() 写文件 f.writeable() 是否可写 f.writelines() 要接收一个容器类型 for i in l: f.write(i) f.writeline() 写一行 '''
二、文件打开模式补充(r+,w+,a+,t,b)和文件指针的移动
r+:读写模式 比r模式多了可写,且在尾部追加写 其余与r模式一样 w+:写读模式 比w模式多了可读 其余与w模式一样 a+:追加写且可读模式 比a模式多了可读 其余与a模式一样 t:文本模式 只能和r/w/a连用 并且不写的情况下 默认就是t t模式下必须指定encoding参数 b:原生的二进制数据 只能和r/w/a连用 该模式通常用来处理非文本文件 直接存储网络上传输过来的二进制数据 b模式下必须不能指定encoding参数 f.seek()的用法 f.seek(offset,whence) offset:相对偏移量 光标移动的位数 whence: 0:参照文件的开头 t和b都可以使用 1:参照光标所在的当前位置 只能在b模式下用 2:参照文件的末尾 只能在b模式下使用 在任何模式下,seek()移动的都是字节数。在可读的t模式下,read读的是字符数
在文件的非末尾处写入内容将会覆盖后面的内容,有可能会导致文件乱码(*****)
三、写日志,检测文件内容,截断文件
#写日志 import time res = time.strftime('%Y-%m-%d %X') with open(r'test01.txt','a',encoding='utf-8') as f: f.write('%s egon给jason发了1个亿的工资 '%res) #检测文件内容 with open(r'test01.txt','rb') as f: # 先将光标移动到文件末尾 f.seek(0,2) while True: res = f.readline() # 查看光标移动了多少位 bytes # print(f.tell()) if res: print("新增的文件内容:%s"%res.decode('utf-8')) # 说明有人操作当前文件 # else: # # 说明文件没有被任何人操作 # print('暂无其他人操作该文件') #截断文件 with open(r'test','a',encoding='utf-8') as f: f.truncate(6) # 接收的字节的长度 整型 # 保留0~6字节数 后面的全部删除(截断)
四、修改文件
# 修改文件方式一 # 先将数据由硬盘读到内存(读文件) # 在内存中完成修改(字符串的替换) # 再覆盖原来的内容(写文件) with open(r'test02.txt','r',encoding='utf-8') as f: data = f.read() print(data) print(type(data)) with open(r'test02.txt','w',encoding='utf-8') as f: res = data.replace('egon','jason') print(data) f.write(res) # 优点:任意时间硬盘上只有一个文件 不会占用过多硬盘空间 # 缺点:当文件过大的情况下,可能会造成内存溢出 # 文件修改方式二 # 创建一个新文件 # 循环读取老文件内容到内存进行修改 将修改好的内容写到新文件中 # 将老文件删除 将新文件的名字改成老文件名 import os with open(r'test02.txt','r',encoding='utf-8') as read_f, open(r'test02.swap','a',encoding='utf-8') as write_f: for line in read_f: new_line = line.replace('jason','egon') write_f.write(new_line) os.remove('test02.txt') os.rename('test02.swap','test02.txt') # 优点:内存中始终只有一行内容 不占内存 # 缺点:再某一时刻硬盘上会同时存在两个文件