编码&文件操作

 一 编码进阶

"""
Python3中有两种数据类型(注意是数据类型而不是编码方式):str和bytes。str类型存储unicode数据,用于向人展示数据,既我们所说的明文。bytes类型用于存储字节数据,用于计算机存储和传输
"""

二 练习

# s1 = '中国'
# str类型用于向人类展示,计算机不认识,想要存储和网络传输必须先将str转化成bytes类型;
# s2 = s1.encode('utf-8') # utf-8中转化成bytes类型,一个中文==3bytes;
# print(s2)

# 用什么编码的就用什么解码
# s3 = s2.decode('utf-8')
# print(s3)
# 同理GBK编码也是
# ------------------------
# gbk与utf-8的转换
# utf-8<---->unicode<---->gbk
s1 = '中国'
# 首先将字符串编码成bytes类型才能传输
a = s1.encode('utf-8') # 发送bytes类型
# 接收者首先需要将a解码成unicode编码(万国码)
a1 = a.decode('utf-8')
# 在编码成gbk格式用于存储
a2 = s1.encode('gbk')
# 解码gbk查看
a3 = a2.decode('gbk')
print(a3)
View Code

 

三 编码的进阶 

# str -----> utf-8 bytes
a = '中国'
b = a.encode('utf-8')
print(b)   # b'\xe4\xb8\xad\xe5\x9b\xbd'
# str -----> gbk bytes
c = a.encode('gbk')
print(c)   # b'\xd6\xd0\xb9\xfa'

# utf-8 bytes ------> str  uniconde
demo = b'\xe4\xb8\xad\xe5\x9b\xbd'
str_l = demo.decode('utf-8')
print(str_l)

# gbk bytes ------> str  uniconde
demo1 = b'\xd6\xd0\xb9\xfa'
str_2 = demo1.decode('gbk')
print(str_2)

# 终极转换  utf-8 ------> gbk  两者之间的转换必须通过万国码(unicode)
t = b'\xe4\xb8\xad\xe5\x9b\xbd'
# 先将utf-8编码转换成unicode
y = t.decode('utf-8')
# 在将y编码成gbk
u= y.encode('gbk')
print(u)
View Code

四 文件操作

1 文件操作:
#1. 打开文件的模式有(默认为文本模式):
r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
w,只写模式【不可读;不存在则创建;存在则清空内容】
a, 只追加写模式【不可读;不存在则创建;存在则只追加内容】

#2. 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的jgp格式、视频文件的avi格式)
rb
wb
ab
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码

#3,‘+’模式(就是增加了一个功能)
r+, 读写【可读,可写】
w+,写读【可写,可读】
a+, 写读【可写,可读】

#4以bytes类型操作的读写,写读,写读模式
r+b, 读写【可读,可写】
w+b,写读【可写,可读】
a+b, 写读【可写,可读】

r+ 读写模式:先读后写

rb 以字节的形式读取,带b的一般操作的都是非文字类的文件.
read:读取全部内容(文件较大时不可用,用for循环读取)
r模式:read(n)----n代表读取第几个字符
rb模式:read(n)---n代表读取第几个字节
其余的文件内光标移动都是以字节为单位的如:seek,tell,truncate
readlien:读取第一行
readliens:返回一个list 列表的每个元素是源文件的每一行.
View Code


重点:seek光标移动(按字节移动)中文3个字节,英文一个字节,换行(\n)是2个字节;
seek(0,0)把光标移到起始位置
seek(0,1)当前光标所在位置
seek(0,2)把光标移到结束位置
r模式:read(n)----n代表读取第几个字符,只有r模式n代表字符,其他都是按字节读取


1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果。

五 常用操作

1.seek(n) 光标移动到n位置, 注意, 移动的单位是byte. 所以如果是UTF-8的中文部分要
是3的倍数.
通常我们使⽤seek都是移动到开头或者结尾.
移动到开头: seek(0)
移动到结尾: seek(0,2) seek的第二个参数表⽰的是从哪个位置进行偏移, 默认是0, 表示开头, 1表示当前位置, 2表示结尾

f = open("⼩娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光标移动到开头
content = f.read() # 读取内容, 此时光标移动到结尾
print(content)
f.seek(0) # 再次将光标移动到开头
f.seek(0, 2) # 将光标移动到结尾
content2 = f.read() # 读取内容. 什么都没有
print(content2)
f.seek(0) # 移动到开头
f.write("张国荣") # 写⼊信息. 此时光标在9 中⽂3 * 3个 = 9
f.flush()
f.close()
View Code

 

 

2.tell() 使用tell()可以帮我们获取到当前光标在什么位置

f = open("⼩娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光标移动到开头
content = f.read() # 读取内容, 此时光标移动到结尾
print(content)
f.seek(0) # 再次将光标移动到开头
f.seek(0, 2) # 将光标移动到结尾
content2 = f.read() # 读取内容. 什么都没有
print(content2)
f.seek(0) # 移动到开头
f.write("张国荣") # 写入信息. 此时光标在9 中文3 * 3个 = 9
print(f.tell()) # 光标位置9
f.flush()
f.close()
View Code

 

 

3.truncate() 截断⽂件 

f = open("⼩娃娃", mode="w", encoding="utf-8")
f.write("哈哈") # 写⼊两个字符
f.seek(3) # 光标移动到3, 也就是两个字中间
f.truncate() # 删掉光标后⾯的所有内容
f.close()
f = open("⼩娃娃", mode="r+", encoding="utf-8")
content = f.read(3) # 读取12个字符
f.seek(4)
print(f.tell())
f.truncate() # 后⾯的所有内容全部都删掉
# print(content)
f.flush()
f.close()
View Code

 

 

深坑请注意: 在r+模式下. 如果读取了内容. 不论读取内容多少. 光标显示的是多少. 再写入
或者操作文件的时候都是在结尾进行的操作.
所以如果想做截断操作. 记住了. 要先挪动光标. 挪动到你想要截断的位置. 然后再进⾏截断
关于truncate(n), 如果给出了n. 则从开头开头进行截断, 如果不给n, 则从当前位置截断. 后⾯
的内容将会被删除

六 文件的修改以及另一种打开文件句柄的方式

文件修改: 只能将文件中的内容读取到内存中, 将信息修改完毕, 然后将源文件删除, 将新文件的名字改成老文件的名字.

# ⽂件修改
import os
with open("⼩娃娃", mode="r", encoding="utf-8") as f1,\
 open("⼩娃娃_new", mode="w", encoding="UTF-8") as f2:
 content = f1.read()
 new_content = content.replace("冰糖葫芦", "⼤⽩梨")
 f2.write(new_content)
os.remove("⼩娃娃") # 删除源⽂件
os.rename("⼩娃娃_new", "⼩娃娃") # 重命名新⽂件
View Code

  

弊端: 一次将所有内容进行读取. 内存溢出. 解决方案: 一行一行的读取和操作

import os
with open("⼩娃娃", mode="r", encoding="utf-8") as f1,\
 open("⼩娃娃_new", mode="w", encoding="UTF-8") as f2:
 for line in f1:
 new_line = line.replace("⼤⽩梨", "冰糖葫芦")
 f2.write(new_line)
os.remove("⼩娃娃") # 删除源⽂件
os.rename("⼩娃娃_new", "⼩娃娃") # 重命名新⽂件
View Code

 

posted @ 2019-07-13 18:42  self哥  阅读(231)  评论(0编辑  收藏  举报