文件操作
目录
文件操作
一.字符编码
1.字符编码理论
该知识点理论特别多 但是结论很少 代码使用也很短
1.字符编码只针对文本数据
2.回忆计算机内部存储数据的本质
3.既然计算机内部只认识01 为什么我们却可以敲出人类各式各样的字符
肯定存在一个数字跟字符的对应关系 存储该关系的地方称为>>>:字符编码本
4.字符编码发展史
4.1.一家独大
计算机是由美国人发明的 为了能够让计算机识别英文
需要发明一个数字跟英文字母的对应关系
ASCII码:记录了英文字母跟数字的对应关系
用8bit(1字节)来表示一个英文字符
4.2.群雄割据
中国人
GBK码:记录了英文、中文与数字的对应关系
用至少16bit(2字节)来表示一个中文字符
很多生僻字还需要使用更多的字节
英文还是用8bit(1字节)来表示
日本人
shift_JIS码:记录了英文、日文与数字的对应关系
韩国人
Euc_kr码:记录了英文、韩文与数字的对应关系
"""
每个国家的计算机使用的都是自己定制的编码本
不同国家的文本数据无法直接交互 会出现"乱码"
"""
4.3.天下一统
unicode万国码
兼容所有国家语言字符
起步就是两个字节来表示字符
utf系列:utf8 utf16 ...
专门用于优化unocide存储问题
英文还是采用一个字节 中文三个字节
2.字符编码实操
1.针对乱码不要慌 切换编码慢慢试即可
2.编码与解码
编码:将人类的字符按照指定的编码编码成计算机能够读懂的数据
字符串.encode()
解码:将计算机能够读懂的数据按照指定的编码解码成人能够读懂
bytes类型数据.decode()
3.python2与python3差异
python2默认的编码是ASCII
1.文件头
# encoding:utf8
2.字符串前面加u
u'你好啊'
python3默认的编码是utf系列(unicode)
二.文件操作
1.文件的概念
就是操作系统暴露给用户操作硬盘的快捷方式
eg:双击一个文件夹 其实是从硬盘将数据加载到内存
ctrl+s保存文件 其实是将内存中的数据刷到硬盘保存
2.代码打开文件的两种方式
方式1:
f = open(文件路径, 读写模式, encoding='utf8')
f.close()
方式2
with open('a.txt', 'r', encoding='utf8') as f1:
with子代码块
ps:with上下文管理号处在于子代码运行结束自动调用close方法关闭资源
"""
open方法的第一个参数是文件路径并且撬棍跟一些字母的组合会产生特殊的含义导致路径查找混乱 为了解决该问题可以在字符串的路径前面加字母r
D:\a\n\t
r'D:\a\n\t'
以后涉及到路径的编写 推荐加上r
with支持一次性打开多个文件
with open() as f1, open() as f2, open() as f3:
子代码
"""
三.文件读写模式
1. 'r' 只读模式:只能读不能写
1.文件路径不存在:会直接报错
with open(r'b.txt', 'r', encoding='utf8') as f:
print(f.read())
2.文件路径存在:正常读取文件内容
with open(r'a.txt', 'r', encoding='utf8') as f:
print(f.read())
2. 'w' 只写模式:只能写不能看
1.文件路径不存在:自动创建
with open(r'b.txt', 'w', encoding='utf8') as f:
pass
2.文件路径存在:先清空文件内容 之后再写入
with open(r'a.txt', 'w', encoding='utf8') as f:
f.write('假期综合症 赶紧要调整\n')
f.write('假期综合症 赶紧要调整\n')
f.write('假期综合症 赶紧要调整\n')
'''强调:换行符需要自己添加 并且在后续数据读取比对的时候也一定要注意它的存在'''
3. 'a' 只追加模式:文件末尾添加数数据
1.文件路径不存在:自动创建
with open(r'c.txt', 'a', encoding='utf8') as f:
f.write('哦累累')
"""
当我们在编写代码的时候 有些部分不知道写什么具体代码 但是也不能空着不写
这个时候可以使用关键字
pass
...
只补全语法不执行功能 本身没有任何的含义
"""
四.文件操作模式
1. t 文本模式
默认的模式,我们上面所介绍的r w a其实全称是rt wt at
1.只能操作文本文件
2.读写都是以字符为单位
3.需要指定encoding参数 如果不知道则会采用计算机默认的编码
t 模式的使用
with open('a.txt', 'rt', encoding='utf8') as f:
res = f.read()
print(type(res)) # 输出结果为:<class 'str'>
with open('a.txt', 'wt', encoding='utf8') as f:
s = 'abc'
f.write(s) # 写入的也必须是字符串类型
2. b 二进制模式(bytes模式)
不是默认的模式 需要自己指定 rb wb ab
1.可以操作任意类型的文件
2.读写都是以bytes为单位
3.不需要指定encoding参数 因为他已经是二进制模式了 不需要编码
b 模式的使用
with open('1.mp4', 'rb') as f:
data = f.read()
print(type(date)) # 输出结果为:<class 'bytes'>
with open('a.txt', 'wb') as f:
msg = '你好'
res = msg.encoding('utf8') # res为bytes类型
f.write(res) # 在b模式下写入文件的只能是bytes类型
强调:b模式对比t模式
1、二进制模式与文本模式针对文件路径是否存在的情况下规律是一样的!!!
2、在操作纯文本文件方面t模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以此时t模式更为方便
3、针对非文本文件(如图片、视频、音频等)只能使用b模式
五.文件的诸多方法
1.read()
一次性读取文件内容 并且光标停留在文件末尾 继续读则没有内容
并且当文件内容比较多的时候 该方法还可能造成计算机内存溢出
括号内还可以填写数字 在文本模式下 表示读取几个字符
2.for循环
一行行读取文件内容 避免内存溢出现象的产生
3.readline
一次只读一行内容
4.readlines()
一次性读取文件内容 会按照行数组织成列表的一个个数据值
5.readable()
判断文件是否具备读数据的能力
6.write()
写入数据
7.writeable()
判断文件是否具备写数据的能力
8.writelines()
接收一个列表 一次性将列表中所有的数据值写入
9.flush()
讲内存中文件数据立刻刷到硬盘 等价于ctel+s
六.文件内光标的移动
之前文件内指针的移动都是由读/写操作而被动触发的,若想读取文件某一特定位置的数据,则需要用f.seek方法主动控制文件内指针的移动,详细用法如下:
with open(r'a.txt', 'rb') as f:
print(f.read())
f.seek(0, 0)
print(f.read())
print(f.read(2).decod('utf8'))
f.seek(-1, 2)
print(f.tell()) # 返回光标距离文件开头产生的字节数
"""
seek(offset, whence)
offset是位移量 以字节为单位
whence是模式 0 1 2
0:默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
1:该模式代表指针移动的字节数是以当前所在的位置为参照的
2:该模式代表指针移动的字节是以文件末尾的位置为参照的
强调:其中0模式可以在t或b模式使用,而1跟2模式只能在b模式下使用
"""
案例(了解)
import time
with open(r'a.txt', 'rb') as f:
f.seek(0, 2)
while Ture:
line = f.readline()
if len(line) == 0:
# 没有内容
time.sleep(0.5)
else:
print(line.decode('utf8'), end='')
七.计算机硬盘修改数据的原理(了解)
硬盘写数据可以看成是在硬盘上刻字 一旦需要修改中间内容 则需要重新刻字 因为刻过的字不可能从中间再分开
硬盘删除数据的原理
不是直接删除而是改变状态 等待后续数据的覆盖才会被真正删除
八.文件内容修改
修改文件内容方式1:覆盖写
with open(r'a.txt', 'r', encoding='utf8') as f:
data = f.read()
with open(r'a.txt', 'w', encoding='utf8') as f1:
f1.write(data.replace('jason', 'tony'))
修改文件内容的方式2:换地写
'''先在另外一个地方写入内容 然后将源文件删除 将新文件命名成源文件'''’
import os
with open('a.txt', 'r', encoding='utf8') as read_f, \ open('.a.txt.swap', 'w', encoding='utf8') as write_f:
for line in read_f:
write_f.write(line.replace('tony', 'kevin'))
os.remove('a.txt') # 删除a.txt
os.rename('.a.txt.swap', 'a.txt') # 重命名文件