参考百度百科:
https://baike.baidu.com/item/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81/8446880?fr=aladdin
''' 1 什么是文件 文件是操作系统为用户/应用程序提供的一种操作硬盘的抽象单位 2 为何要用文件 用户/应用程序对文件的读写操作会由操作系统转换成具体的硬盘操作 所以用户/应用程序可以通过简单的读\写文件来间接地控制复杂的硬盘的存取操作 实现将内存中的数据永久保存到硬盘中 user=input('>>>>: ') #user="小王" 3 如何用文件 文件操作的基本步骤: f=open(...) #打开文件,拿到一个文件对象f,f就相当于一个遥控器,可以向操作系统发送指令 f.read() # 读写文件,向操作系统发送读写文件指令 f.close() # 关闭文件,回收操作系统的资源 上下文管理: with open(...) as f: pass ''' # 绝对路径 f = open(r'/Users/jaidun/data/python_space/a.txt', encoding='utf-8') print(f.read()) f.close() # 相对路径 # 读取当前文件 f = open(r'a.txt', encoding='utf-8') # ../相对路径 f = open(r'../a.txt', encoding='utf-8') print(f.read()) f.close() # # 强调:一定要在程序结束前关闭打开的文件 # 可能会忘记 # # f.close() # print(f.read()) # 上下文管理:with # with open(...) as f: # pass # 可以自动关闭文件 with open(r'a.txt', encoding='utf-8')as f: print(f.read()) # print(f.read())
一 文件的打开模式
r: 只读模式(默认的)
w: 只写模式
a: 只追加写模式
二 控制读写文件单位的方式(必须与r\w\a连用)
t : 文本模式(默认的),一定要指定encoding参数
优点: 操作系统会将硬盘中二进制数字解码成unicode然后返回
强调:只针对文本文件有效
b: 二进制模式,一定不能指定encoding参数
优点:可以网络直接传输
#一 r: 只读模式(默认的) # 1 当文件不存时,会报错 # 2 当文件存在时,文件指针指向文件的开头 with open('a.txt',mode='rt',encoding='utf-8')as f: res1=f.read() print('111>>>',res1) # # 第一次读完了 res2 = f.read() print('222>>>', res2) # 判断rt模块可读 print(f.readable()) # # 判断rt模式不可写 print(f.writable()) # read 文件太大不好 print(f.readline(),end='') # # #文件里面有换行符 print自带换行符\n print(f.readline()) # for循环遍历文件对象 for line in f: print(line,end='') L = [] for line in f: L.append(line) print(L) # 一行代码搞定 print(f.readlines())
# 二 wt: 只写模式 # 1 当文件不存时,新建一个空文档(无则创建) # with open('b.txt',mode='wt',encoding='utf-8')as f: # pass # 2 当文件存在时,清空文件内容,文件指针跑到文件的开头(有则清空) with open('b.txt',mode='wt',encoding='utf-8')as f: # 全部清空 # 下面写我们想要的内容 # 不能读 print(f.readable()) # 可以写 print(f.writable()) # f.read() # 记得要写换行符 # 把之前的内容覆盖了 # f.write(字符串) f.write('小王\n') f.write('大王\n') f.write('小戴\n') # 一次性写多行 f.write('111\n2222\n3333\n') # 把列表内容一行行写入 info = ['大海\n','大海\n','大海\n'] for line in info: f.write(line) # 一行代码搞定 # writelines(列表) f.writelines(info)
# 三 at: 只追加写模式 # 1 当文件不存时,新建一个空文档,文件指针跑到文件的末尾(开头就是末尾) # with open('c.txt',mode='at',encoding='utf-8')as f: # pass # 2 当文件存在时,文件指针跑到文件的末尾 with open('c.txt',mode='at',encoding='utf-8')as f: # 不能读 print(f.readable()) # 能写 print(f.writable()) f.write('小王老师\n') f.write('小戴老师\n') f.write('小周老师\n') with open('c.txt',mode='at',encoding='utf-8')as f: # 不能读 print(f.readable()) # 能写 print(f.writable()) f.write('戴老师\n') f.write('杨老师\n') f.write('付老师\n')
w模式和a模式的区别
wt模式
在文件打开不关闭的情况下,连续的写入,
下一次写入一定是基于上一次写入指针的位置而继续的
a模式关闭了下次打开是在文件末尾写,所以不会覆盖之前的内容
二 控制读写文件单位的方式(必须与r\w\a连用)
t : 文本模式(默认的),一定要指定encoding参数
优点: 操作系统会将硬盘中二进制数字解码成unicode然后返回
强调:只针对文本文件有效
b: 二进制模式,一定不能指定encoding参数
优点:可以直接网络传输
# 只能对文本文件操作 t 模式局限性 # 二进制文件 b 模式 # 图片和视频 with open('1.jpeg', mode='rb', )as f: data = f.read() print(data) print(type(data)) with open('2.jpeg', mode='wb')as f1: f1.write(data) # 用b模式,也可以对文本文件操作,但是要解码 # decode 二进制解码成字符 # encode 字符编码成二进制 # 解码 读的时候转换成字符 with open('b模式.txt', mode='rb')as f: data = f.read() print(data) print(data.decode('utf-8')) # 编码 写的时候把字符转换成二进制写入 with open('wb模式.txt', mode='wb')as f: f.write('小红\n'.encode('utf-8')) f.write('小王\n'.encode('utf-8')) f.write('小戴\n'.encode('utf-8'))
1 当文件不存时,会报错
2 当文件存在时,文件指针指向文件的开头
3 多了个末尾写
with open('可读可写r+t模式.txt', mode='r+t', encoding='utf-8')as f: print(f.readable()) print(f.writable()) msg = f.readline() print(msg) f.write('xxxxxxxx')
1 当文件不存时,新建一个空文档(无则创建)
2 当文件存在时,清空文件内容,文件指针跑到文件的开头(有则清空)
with open('可读可写w+t模式.txt', mode='w+t', encoding='utf-8')as f: print(f.readable()) print(f.writable()) f.write('aaaaaaaa\n') f.write('bbbbbbbb\n') # 指针移动seek(移动的字节数,开头开始0) # 从开头开始移动0 f.seek(0, 0) print(f.readline()) f.write('cccccccc\n')
第二次打开时候也是在末尾写
with open('可读可写a+t模式.txt',mode='a+t',encoding='utf-8')as f: print(f.readable()) print(f.writable()) f.write('aaaaaaaa\n') f.write('bbbbbbbb\n') # 指针移动seek(移动的字节数,开头开始0) # 从开头开始移动0 f.seek(0,0) print(f.readline()) f.write('cccccccc\n') # 图片和视频用不上 # r+b w+b a+b 规律和r+t w+t a+t
文件内指针移动
t模式下的read(n),n代表的字符的个数
b模式文件内指针的移动都是以字节为单位
指针操作
f.seek(offset,whence)有两个参数:
offset: 代表控制指针移动的字节数
whence: 代表参照什么位置进行移动
whence = 0: 参照文件开头(默认的),特殊???,可以在t和b模式下使用
whence = 1: 参照当前所在的位置,必须在b模式下用
whence = 2: 参照文件末尾,必须在b模式下用
# t模式 # with open('指针移动.txt',mode='rt',encoding='utf-8')as f: # print(f.read(1)) # print(f.read(1)) # print(f.read(1)) # b模式 # with open('指针移动.txt', mode='rb')as f: # # 2个16进制是2**4 2**8 # # 三分之一个汉字 # print(f.read(1).decode('utf-8')) # print(f.read(1).decode('utf-8')) # print(f.read(3).decode('utf-8')) # print(f.read(3).decode('utf-8')) # print(f.read(3).decode('utf-8')) # 指针操作 # f.seek(offset,whence)有两个参数: # offset: 代表控制指针移动的字节数 # whence: 代表参照什么位置进行移动 # whence = 0: 参照文件开头(默认的),特殊???,可以在t和b模式下使用 # whence = 1: 参照当前所在的位置,必须在b模式下用 # whence = 2: 参照文件末尾,必须在b模式下用 # t模式 按照字符算 with open('seek.txt',mode='rt',encoding='utf-8')as f: f.seek(2,0) print(f.read(1)) # b模式 移动的字节数 读的也是字节数 with open('seek.txt',mode='rb')as f: f.seek(5,0) print(f.read(3).decode('utf-8')) with open('seek.txt',mode='rb')as f: msg = f.read(5) # 当前光标所在的字节数 print(f.tell()) f.seek(3,1) print(f.read(3).decode('utf-8')) with open('seek.txt',mode='rb')as f: f.seek(0,2) print(f.tell()) f.seek(-3,2) print(f.read(3).decode('utf-8'))
with open('历史.txt',mode='rb')as f: f.seek(0,2) while True: line=f.readline() # 如果是0个bytes意味着光标在最后 # 没有关闭这个文件操作 if len(line) != 0: print(line.decode('utf-8'),end= '')
1 将文件内容由硬盘全部读入内存
2 在内存中完成修改
3 将内存中修改后的结果覆盖写回硬盘
with open('文件修改.txt', mode='rt', encoding='utf-8')as f: all_data = f.read() # # 读出来的数据已经存到all_data变量里面的了 with open('文件修改.txt', mode='wt', encoding='utf-8')as f1: f1.write(all_data.replace('小王', '大王'))
1 以读的方式打开源文件,以写的方式打开一个临时文件
2 从源文件中每读一样内容修改完毕后写入临时文件,直到源文件读取完毕
3 删掉源文件,将临时文件重命名为源文件名
import os with open('文件修改二.txt',mode='rt',encoding='utf-8')as read_f,open('临时文件.txt',mode='wt',encoding='utf-8') as write_f: for line in read_f: write_f.write(line.replace('小戴','小杨')) # 文件修改二删除 os.remove('文件修改二.txt') # # 临时文件.txt 改成 文件修改二 os.rename('临时文件.txt','文件修改二.txt')
方式一:
优点: 在文件修改的过程中硬盘上始终一份数据
缺点: 占用内存过多,不适用于大文件
方式二:
优点: 同一时刻在内存中只存在源文件的一行内容,不会过多地占用内存
缺点: 在文件修改的过程中会出现源文件与临时文件共存,硬盘上同一时刻会有两份数据,即在修改的过程中会过多的占用硬盘,
# 天生我才必有用 # 日语 with open('text1.txt', mode='w', encoding='shift_jis')as f1: f1.write('生まれながらにしてわたくし私はかならず必ずやく役にたつ立つ') # with open('text1.txt', mode='r', encoding='utf-8')as f1: # a = f1.read() # print(a) # 英文 with open('text2.txt', mode='w', encoding='shift_jis')as f1: f1.write('I believe') with open('text2.txt', mode='r', encoding='utf-8')as f2: a = f2.read() print(a)
!!!总结非常重要的两点!!!
1、保证不乱码的核心法则就是,字符按照什么标准而编码的,
就要按照什么标准解码,此处的标准指的就是字符编码
2、在内存中写的所有字符,一视同仁,都是unicode编码,比如我们打开编辑器,
输入一个“你”,我们并不能说“你”就是一个汉字,此时它仅仅只是一个符号,
该符号可能很多国家都在使用,根据我们使用的输入法不同这个字的样式可能也不太一样。
只有在我们往硬盘保存或者基于网络传输时,
才能确定”你“到底是一个汉字,还是一个日本字,这就是unicode转换成其他编码格式的过程了