1、文件的打开方式
1.1 基本描述
如果被打开的文档原来是utf-8编码,这时候只是改变编码为GB2312,那么用utf-8读是不会乱码的,而改为GB2312以后,重新输入字符,然后用utf-8打开则报错,说明文件只是编码改变,但没有在新编码下进行输入,则原来的字符按旧编码还是可以正确读出来的一个文件用什么编码方式保存,那么就要用什么编码形式打开只读、只写、追加、读写、如果电脑中“组织”中选择了“隐藏已知文件类型的扩展名”,再用带扩展名打开则会给文件再加一个扩展名,则不要选中这个选项。打开一个文件,操作完成以后,就要关闭这个文件。文件以什么编码存储,就要用什么编码打开
1.2 操作绝对路径
1 f = open('E:\Python Project\\05\Day8\模特主妇护士老师.txt',mode= 'r',encoding='utf-8') 2 content = f.read() 3 print(content) 4 f.close()
结果:
1 中国广东广州
1.3 操作相对路径
1 f = open('模特主妇护士老师.txt',mode= 'r',encoding='utf-8') 2 content = f.read() 3 print(content) 4 f.close()
结果:
1 中国广东广州
1.3 只读r:
1 f = open('模特主妇护士老师.txt',mode= 'r',encoding='utf-8') 2 content = f.read() 3 print(content,type(content)) 4 f.close()
结果:
1 中国广东广州 <class 'str'>
1.4只写w:
1 f = open('模特主妇护士.txt',mode= 'w',encoding='utf-8') 2 content = f.write('peng') 3 print(content,type(content)) 4 f.close()
结果:
1 4 <class 'int'>
1.5 wb:
1 f = open('模特主妇护士.txt',mode= 'wb') 2 content = f.write('peng333'.encode('utf-8')) #py默认就是以utf-8编码的,所以不会报错 3 print(content,type(content)) 4 f.close()
结果:
1 7 <class 'int'>
1.6追加a
1 f = open('log',mode= 'a',encoding= 'utf-8') 2 f.write("fei") 3 f.close()
结果:
文件中有添加
1.7 追加ab
1 f = open('log',mode= 'ab') 2 f.write("fei".encode('utf-8')) 3 f.close()
结果:
为空
1.8 读写r+
读写r+:读写【可读,可写】,先读后写,如果先写那么光标定位在开始位置,会把已有的内容覆盖掉,然后读从写完那个位置开始读
这个最常用
1 f = open('log',mode='r+',encoding='utf-8') 2 print(f.read()) 3 f.write('AAA') 4 f.close()
结果:
1 AAAAAAAAAAAAAAAAAAfeifeifeifei
1 下面就是先写后读,那么光标位置就变化了 2 f = open('log',mode='r+',encoding='utf-8') 3 f.write('AAA') 4 print(f.read()) 5 f.close()
1.9 r+b:
1 f = open('log',mode='r+b') 2 print(f.read()) 3 f.write('AAA'.encode('utf-8')) 4 f.close()
结果:
b'AAAAAAAAAAAAAAAAAAfeifeifeifeiAAAAAA'
1.10 w+:写读【可写,可读】
写读【可写,可读】,先清除在写,然后再读
1 f = open('log',mode='w+',encoding='utf-8') 2 f.write('AAA') 3 f.seek(0) 4 print(f.read()) 5 f.close()
结果:
AAA
1.11 a+:
1 f = open('log',mode='a+',encoding='utf-8') 2 f.write('AAA') 3 f.seek(0) 4 print(f.read()) 5 f.close()
结果:
1 AAAAAA
1.12 ab:
1 原来文件的数据如下: 2 fr43r3r
运行下面的代码后:
1 f = open('log',mode= 'ab') 2 f.write("fei".encode('utf-8')) 3 f.close()
结果:
1 fr43r3rfei
2、文件的光标定位及操作
2.1 seek()与read()的区别
read():读出来的是都是字符,字符是能看到完整的字符,比如一个字符a,或者一个中文:彭;括号里面为空则表示从头读到最后,如果有数字表示读多少个字符。
seek():是按字节找光标,在utf-8里中文是三个字节表示,字母是1个字节表示,所以用seek()要注意光标定位,不要定位到中文字符的其中一个字节,否则会报错。
2.1 如果文件中的内容是:AA彭广东,那么下面的读出来的效果是
第一种代码:
1 f = open('log', mode= 'r', encoding='utf-8') 2 content = f.read() 3 print(content) 4 f.close()
结果:
1 AA彭广东
第二种代码:
1 f = open('log', mode= 'r', encoding='utf-8') 2 content = f.read(3) 3 print(content) 4 f.close()
结果:
1 AA彭
2.2 如果文件中内容是:AA彭广东,那么下面读结果是否报错
第一种代码:
1 f = open('log', mode= 'r+', encoding='utf-8') 2 f.seek(5) 3 content = f.read() 4 print(content) 5 f.close()
结果:
1 广东
第二种代码:
1 f = open('log', mode= 'r+', encoding='utf-8') 2 f.seek(3) 3 content = f.read() 4 print(content) 5 f.close()
结果:
1 Traceback (most recent call last): 2 File "E:/Python Project/05/Day8/文件操作.py", line 118, in <module> 3 content = f.read() 4 File "E:\Python Project\05\venv\lib\codecs.py", line 321, in decode 5 (result, consumed) = self._buffer_decode(data, self.errors, final) 6 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbd in position 0: invalid start byte
2.3 用tell()解决文件传输过程断点续传问题
tell:作用就是时刻检测当前光标的位置
要解决断点续传问题,那么就得知道光标的位置,然后把光标移到断开的位置,重新传输即可
如果文件中的内容:AA彭广东广东,那么下面代码的结果是什么?
1 f = open('log', mode= 'a+', encoding='utf-8') 2 f.write('广东') 3 count = f.tell() #得到当前光标位置 4 f.seek(count-9) #光标位置后退9个字节 5 content = f.read(2) 6 print(content) 7 f.close()
结果:
1 东广
2.4 读取一行
readline:就是简单地读取一行;
1 f = open('log', mode= 'r+', encoding='utf-8') 2 line = f.readline() #读取一行 3 print(line) 4 f.close()
结果:
1 AA彭广东广东广东
readlines:读取多行,然后把每一行当作列表的元素添加到列表中:
1 f = open('log', mode= 'r+', encoding='utf-8') 2 line = f.readlines() #每一行当成列表的元素,然后添加到列表中 3 print(line) 4 f.close()
结果:
1 ['AA彭广东广东广东\n', 'ggerger\n', 'tggr\n']
按行读取还可以用for循环实现:
1 f = open('log', mode= 'r+', encoding='utf-8') 2 for line in f: 3 print(line) 4 f.close()
2.5 对文件进行截取:
truncate(N):截取文件的前N个字符,然后把后面的删除
如果文件中的内容是:AA彭abc,那么下面代码的结果是什么
1 f = open('log', mode= 'r+', encoding='utf-8') 2 li = f.truncate(5) #截取5个字符 3 print(li) 4 conent = f.read() 5 print(conent) 6 f.close()
结果:
1 5 2 AA彭
2.6 with....as...语句:
这个语句主要是相当普通的open()文件必须配对close()文件,with...as则无需用close()文件,这样避免漏关闭文件
如果文件中的内容为:AA彭
那么下面的代码结果是
1 with open('log',mode='r+',encoding='utf-8') as obj: 2 print(obj.read())
结果:
1 AA彭
用with...as同时打开多个文件
1 with open('log',mode='r+',encoding='utf-8') as f,open('log',mode='w+',encoding='utf-8') as obj: 2 print(f.read())
用with open() as obj1, open() as obj2 打开多个文件
1 with open('log',mode='r+',encoding='utf-8') as f,open('user_id',mode='r+',encoding='utf-8') as obj: 2 print(f.read()) 3 print(obj.read()) 4 结果: 5 dfgggg 6 pengzhangfffsfsf
3、文件注册及登录
要求:输入注册名及密码进行注册,并把注册信息保存到文件中;然后进行登录验证,把登录的内容与文件中读取的内容作比较,看是否相同,如果相同则登录成功:
1 username = input("请输入你的注册名:") 2 userpassword = input("请输入你的注册密码:") 3 4 with open('user_id',mode='w',encoding='utf-8') as f1: 5 f1.write("{}\n{}".format(username,userpassword)) 6 7 count = 0 8 list2 = [] 9 while count < 3: 10 user = input("请输入你的用户名:") 11 password = input("请输入你的密码:") 12 with open('user_id',mode='r+',encoding='utf-8') as f2: 13 for line in f2: 14 list2.append(line) 15 for num in list2: 16 print(num) 17 if user == list2[0].strip() and password == list2[1].strip():#用strip()去除回车 18 print("恭喜你登录成功") 19 break 20 else: 21 print("账号或者密码有误") 22 count += 1
4、编码
4.1 str --->byte encode 编码
1 s = '彭abc' 2 b = s.encode('utf-8') 3 print(b)
结果:
1 b'\xe5\xbd\xadabc'
4.2 byte --->str decode 解码
1 s = '彭abc' 2 b = s.encode('utf-8') 3 print(b) 4 # byte --->str decode 解码 5 s1 = b.decode('utf-8') 6 print(s1)
结果:
1 b'\xe5\xbd\xadabc' 2 彭abc
4.3 byte --->str decode 解码
1 s = 'abf' 2 b = s.encode('utf-8') 3 print(b) 4 #byte --->str decode 解码 5 s1 = b.decode('gbk') 6 print(s1)
结果:
1 b'abf' 2 abf