字符编码
ascii => 各国自己独有的编码(GBK), 兼容ascii => unicode -- utf-8|utf-16
以后文本类型数据采用编码:utf-8
python2默认采用ascii编码表
python3默认采用utf-8
在文件最上方可以通过 # encoding: 编码名来规定文件解码的编码表 -- 文件头
在py3以后的开发环境,所有文件采用utf-8编码存储,py3默认也是采用utf-8读取文件,所有可以省略文件头
u'' = encode('utf-8') > b''
b'' = decode('utf-8') > u''
文件操作
# 打开文件
f = open(r'文件路径', '文件的操作模式', encoding='utf-8')
# 使用文件
f.read()
f.write()
# 关闭文件
f.close()
基础读
# 文件操作模式:r -- 文件必须提前存在,否则抛出异常
# 1.按字符进行操作
# 2.read():读所有内容 | read(10):对指定字符长度
# 3.readline(): 一次读一行
# 4.readlines(): 将文件一行一行读到list中
f = open(r'文件路径', 'r', encoding='utf-8')
基础写
# 文件操作模式:w -- 文件不存在就新建,存在就清空
# 1.按字符进行操作
# 2.write('写入第1行\n写入第2行\n')
# 3.flush(): 将之前写入到内存中的数据刷新到硬盘中
# 4.writelines(list):list中存放的是一条条文件内容,需要明确\n标识换行 writelines(['111\n', '222\n'])
with语法
# 操作系统对文件的支持权由with自动管理释放
with open('file.txt', 'r', encoding='utf-8') as f: # 不需要明文书写f.close()
data = f.read()
print(data)
操作模式
'''
主模式:
r: 文件必须存在的读
w: 文件无需存在的写,无创建,有清空再写
a: 文件无需存在的写,无创建,有在文件最后追加写
从模式:
t: 按文本字符操作数据(默认模式)
b: 按文本字节操作数据
+: 可读可写
了解:
x:新建文件写,如果文件已存在,抛异常
'''
'''
rt | wt | at == r | w | a
rb | wb | ab
rt+ | wt+ | at+ == r+ | w+ | a+
rb+ | wb+ | ab+
'''
游标操作
# 大前提:seek一定在b模式下进行操作,因为seek移动是按字节进行操作
# f.seek(偏移量,操作位置)
f.seek(5, 0) # 从开始往后偏移5个字节
f.seek(-1, 1) # 从当前位置向前偏移1个字节
f.seek(1, 1) # 从当前位置向后偏移1个字节
f.seek(-5, 2) # 从末尾向前偏移5个字节
文件的遍历
# 最常用读写
with open('source', 'r', encoding='utf-8') as f1, open('target', 'w', encoding='utf-8') as f2:
for line in f1:
f2.write(line)
字符编码:
# 乱码:存和取所采用的编码不一致
# 编码:ascii,unicode, gbk, gb2312, utf-8
# 电脑组成:硬盘 - 内存 -(二级缓存、一级缓存、cpu寄存器)- cpu
# cpu交互的是用户能识别的数据:字符
# 硬盘中最终存储的数据:0,1的二进制数据(可以直接转化为电脑能识别的高低电频)
# 什么是字符编码:将人识别的字符转换计算机能识别的01,转换的规则就是字符编码表
''' 编码表 对应关系
你好 <=> 000010001001010101
好的 <=> 001010001001010000
'''
# 最早期对应关系:ascii编码表 - 存放的是英文数字与机器二进制的对应关系
# 数字70对应ascii表,指向的是字母'F'
print(chr(70)) # 'F'
print(ord('f')) # 102
# 字符所占字节数
# 1字节 = 8个二进制位 00000000 ~ 11111111 256个数字 -128 ~ 127
# ascii中一个字母或数字占一个字节
# 中文
# GBK: 16个二进制位 15个0到15个1
# 兼容ascii,一个字母或数字占一个字节
# 2w多汉字,用两个字节进行存储
'''
你好 <=> 00000101010101001011 <=> 콱봤
'''
# 日文/韩文:Shift_JIS、Euc-kr
# 国际上交流:
# 一条信息中,可能同时出现英文/中文/日文/韩文,将所有信息存储,且不乱码
# 万国编码表:unicode
# unicode采用两个字节存放数据:utf-8,utf-16
# utf-8采用变长存储:1字节存放数字与英文,3字节存放汉字
# utf-16采用定长存储:均以2字节存放数字,英文,汉字
# 内存中用utf-16存取数据:定长存取效率高(变长需要计算后才存取)
# cpu中与硬盘中,采用utf-8存放数据(utf-8传输更快)
三种字符串:
# 原文本字符串数据
# s1 = 'abc123你好'
s1 = u'abc123你好'
print(s1)
# 二进制字符串数据: 数据传输是以字节为单位,要将原文字符串转换为二进制字符串机械能传输
# 编码
res = s1.encode('utf-8')
print(res)
# 解码
s2 = res.decode('utf-8')
print(s2)
ss2 = b'abc123\xe4\xbd\xa0\xe5\xa5\xbd\xe5\xa5\xbd\xe5\xa5\xbd'
print('>>', ss2.decode('utf-8'))
# 原义字符串数据
s3 = r'你好\n好的'
print(s3)
# s4 = 'D:\\nbpython周末四期\\day03\\代码\\4.三种字符串.py'
# print(s4)
s4 = r'D:\nbpython周末四期\day03\代码\4.三种字符串.py'
print(s4)
文件操作的基础读写:
# 操作文件的三步骤
# 1、打开文件
# f被程序持有,文件被操作系统持有
# f = open('file.txt', 'r', encoding='utf-8') # r读文件,文件一定要提前存在
# del f
# f.close()
# 2、操作文件
# data = f.read() # 读所有内容
# print(data)
# data = f.read(2) # 读指定字节数或字符数
# print(data)
# d1 = f.read(1) # 在当前位置接着再读1个字节或字符
# print(d1)
# line = f.readline() # 读取一行
# print(line)
# lines = f.readlines() # 按行,将所有行一次一次读出到list中
# print(lines)
# 3、关闭文件
# f.close() # 操作系统对文件的持有权一定要在文件操作完毕后释放
# del f
w = open(r'file.txt', 'w', encoding='utf-8')
w.write('123\n')
w.flush() # 数据量过大时,可以手动将内存中的数据刷新到硬盘中
w.write('456\n')
w.writelines(['000\n', '111\n', '222\n'])
# 是否可读可写
print(w.readable())
print(w.writable())
w.close()
print('end')
操作模式:
'''
主模式:
r: 文件必须存在的读
w: 文件无需存在的写,无创建,有清空再写
a: 文件无需存在的写,无创建,有在文件最后追加写
从模式:
t: 按文本字符操作数据(默认模式)
b: 按文本字节操作数据
+: 可读可写
了解:
x:新建文件写,如果文件已存在,抛异常
'''
# with open语法
# with open('file.txt', 'x', encoding='utf-8') as f: # 不需要明文书写f.close()
# # data = f.read()
# # print(data)
# print(f.readable())
# print(f.writable())
# 追加模式
# with open('file.txt', 'a', encoding='utf-8') as f:
# f.write('123\n')
# print(123)
# print(123)
# f.write('456\n')
# f.flush()
# f.write('789\n')
# 字节方式操作文件
"""
你好
好的
123
"""
# 注:b操作模式下不需要指定encoding,
# 原因,因为b可以对所有类型数据进行操作,包含文本/视频/音频等各种文件
# 而utf-8只是文本文件的编码方式
# 数据在硬盘中本就以二进制进行存储的,所有b默认操作就是对数据从硬盘到内存的拷贝
# with open('file.txt', 'rb') as f:
# data = f.read()
# print(data)
# # 但如果数据要展现给用户,文本文件就要涉及解码,其他文件需要通过专业工具打开
# print(data.decode('utf-8'))
# with open('file.txt', 'ab') as f:
# f.write(b'\n\xe5\x91\xb5\xe5\x91\xb5')
# r+: 从头开始写, a+:从尾开始写, w+:清空写
with open('file.txt', 'rb+') as f:
print(f.readable())
print(f.writable())
# print(f.read())
f.write(b'999')
游标操作:
'''
123
你好
456
'''
with open('file.txt', 'w', encoding='utf-8') as f:
f.write('123\n你好\n456\n')
# 大前提: 游标操作一定要在b模式下进行操作,因为游标一定按字节进行偏移
# seek(偏移量, 操作位置)
# 操作位置:0,从头开始 1,从当前位置开始 2,从最后开始
# with open('file.txt', 'rt', encoding='utf-8') as f:
# d1 = f.read(7)
# print(d1)
# f.seek(1, 0)
# d2 = f.read(1)
# print(d2)
# seek()在操作位置为0时,可以兼容t模式,但任然按字节进行偏移
with open('file.txt', 'rb') as f:
d1 = f.read(14)
print(d1)
# f.seek(1, 1) # 在当前位置往后偏移1个字节
# f.seek(-1, 1) # 在当前位置往前偏移1个字节
f.seek(-3, 2) # 将鼠标移至到文件末尾,往前偏移3个字节
d2 = f.read(1)
print(d2)
修改文件:
# 文件的修改
# rb+:在当前位置进行覆盖书写
with open('change.txt', 'rb+') as f:
f.seek(14, 0)
print(f.read(2))
f.seek(-2, 1)
f.write(b'16')
# ab+:可以操作游标,但只对读起作用,写任然是最后追加
# with open('change.txt', 'ab+') as f:
# f.seek(14, 0)
# print(f.read(2))
# f.seek(-2, 1)
# print(f.read(2))
# f.write(b'18')
with open('change.txt', 'rb+') as f:
data = f.read()
newData = data.decode('utf-8').replace('16', '016')
f.seek(0, 0)
f.write(newData.encode('utf-8'))
复制文件:
# 复制文件
with open('old.txt', 'r', encoding='utf-8') as f1, open('new.txt', 'w', encoding='utf-8') as f2:
# 文件的循环
for line in f1: # 对可读文件对象直接遍历循环,得到的是一行行内容
print(line)
f2.write(line)
import os
with open('001.png', 'rb') as f1, open('002.png', 'wb') as f2:
for line in f1:
f2.write(line)
# 按指定路径将文件删除
os.remove(r'D:\python周末四期\day03\代码\001.png')
秒传案例:
mk = b""
# 计算得到秒传依据
with open('002.png', 'rb') as f:
data = f.read()
# print(data)
length = len(data)
print(length)
# 设置秒传算法:1.截取的部分字节,2.加密字节的算法
# 1.从头开始读10个字节,中间读10个字节,末尾读10个字节
# 2.将所有数据进行拼接
f.seek(0, 0)
d1 = f.read(10)
f.seek(length // 2, 0)
d2 = f.read(10)
f.seek(-10, 2)
d3 = f.read(10)
mk = d1 + d2 + d3
print(mk)
# 实现秒传
with open('200.png', 'rb') as f:
new_mk = b''
f.seek(0, 0)
new_mk += f.read(10)
f.seek(length // 2, 0)
new_mk += f.read(10)
f.seek(-10, 2)
new_mk += f.read(10)
if new_mk == mk:
print('秒传')
else:
print('调用上传方法,进行龟速上传')
# with open('200.png', 'rb+') as f:
# f.seek(-7, 2)
# f.write(b'12')