day 12
内容概括
-
引入
-
文件操作的基本流程
-
文件的操作模式
- 控制文件读写的操作模式
- 控制文件读写内容的模式
-
操作文件的方法
-
主动控制文件内指针移动
-
文件修改
内容详细
-
引入
""" 1、什么是文件 文件是操作系统提供给用户或者说应用程序操作硬盘的一种功能 2、为何要用文件 读写文件就是在读写硬盘:我们对文件的读写操作都会被操作系统转换成硬盘的读写操作 应用程序-------------》文件对象、文件句柄 操作系统-------------》文件 硬件-----------------》硬盘 3、如何用文件 """ # ps: decode:编码 encode:解码 # read().decode write().encode -
文件操作的基本流程
# 由应用程序向操作系统发起系统调用open(),操作系统打开文件,对应一块硬盘空间,并返回一个文件对象赋值给变量f f=open('a.txt',mode='rt',encode='utf-8') # 调用文件对象下的读/写方法,会被操作系统转换为读/写硬盘的操作 res = f.read() # 向操作系统发起关闭文件的请求,回收系统资源 f.close # 回收应用程序级的变量 del f # 但是由于python的自动垃圾回收机制使得我们无需考虑del f # 由于老是会忘记关闭文件,回收系统资源,因此python提供了with关键字来帮我们管理上下文 with open('a.txt',mode='rt',encode='utf-8') as f,\ open(r'c:\d.txt',mode='rt'.encode='utf-8') as f1: ... # 注:这里 as f: 后面的\,是因为代码太长,做个换行,'c:\d.txt'前面的r是用来转义的 # 转义路径中的\ -
文件的操作模式
-
控制文件读写的操作模式
# 1.r(默认) 只读模式 # 2.w 只写模式 # 3.a 只追加模式 # 以下 '|' 我把它当作指针来表示 # 1、r模式:只读模式,如果文件不存在则报错,文件存在则文件指针处于文件开头 with open('a.txt',mode='rt',mode='utf-8') as f: print('第一次读'.center(50,'*')) print(f.read()) # 此时指针位置 xixi| '|'代表指针位置,并且文件处于打开状态并未关闭 # with open(r'a.txt', mode='rt', encoding='utf-8') as f: # 如果这里加了这行代码表示重新打开文件,则能读到xixi print('第二次读'.center(50,'*')) print(f.read()) # 因为指针在 xixi|,后面没有内容,因此读不到内容 # 这里a.txt里的内容为:xixi ''' 输出结果: ***********************第一次读*********************** xixi ***********************第二次读*********************** ''' # 案例: # 验证账号和密码 inp_name = input('请输入账号:').strip() inp_password = input('请输入密码:').strip() with open(r'user.txt',mode='rt',encoding='utf-8') as f: for line in f: username,password = line.strip().split(':') if inp_name == username and inp_password == password: print('login successful') break else: print('username or password error') # 2、w模式:只写模式,如果文件存在则创建空文档,文件存在则清空,文件指针处于文件开头 with open('b.txt,mode='wt',encoding='utf-8') as f: f.read() # 报错 只能写不可读 print(f.write('ycc')) # 指针指向ycc| , print(f.write('ycc\n')) #指针指向下一行开头 # 如果此时我重新运行.py文件(即重新打开b.txt文件),则会清空内容,并重新写入 with open(r'b.txt',mode='wt',encoding='utf-8') as f: f.write('哈哈哈\n') f.write('嘿嘿\n') # 此时我先写了代码f.write('哈哈哈\n'),在b.txt文件没有关闭(即没重新运行.py文件的情况下), # 写代码f.write('嘿嘿\n'),新的内容会跟在就内容之后 # 3.a模式:只追加写,在文件不存在时创建新文档,在文件存在时文件指针会直接跳到末尾 with open(r'c.txt',mode='at',encoding='utf-8') as f: # f.read() # 不可读 报错 f.write('切列1\n') f.write('切列2\n') f.write('切列3\n') # 每次重新运行 a模式.py ,不会清空列表,只会一直添加write()内写的内容 # 强调w模式和a模式的不同 # 相同:在文件没有关闭的情况下,连续的写入,新写的内容会跟在前面写的内容后 # 不同:以a模式打开文件不会清空文件内容,指针会移动至文件末尾 # 案例: # 注册功能 inp_username = input('请输入账号:') inp_password = input('请输入密码:') with open(r'user.txt',mode='at',encoding='utf-8') as f: f.write('{}:{}\n'.format(inp_username,inp_password)) # 文件copy工具 with open('a.txt',mode='rt',encoding='utf-8') as f1,\ open('b.txt',mode='at',encoding='utf-8') as f2: print(f2.write(f1.read())) -
控制文件读写内容的模式
# t(文本模式)(默认):读写都是以字符串为单位的,只适用于文件,必须指定encoding参数 # b(二进制模式):读写都是以butes为单位的,适用于所有文件的,一定不能指定encoding参数 # t模式上面已经介绍完了(rt,wt,at) # 强调:t模式只能用于操作文本文件,无论读写,都是以字符串为单位,而存取硬盘本质都是二进制模式,当我们指定了t模式后,内部帮我们做了编码和解码。 # b模式(以什么编码输入就要以相同的编码格式输出) with open('1.mp4',mode='rb') as f: res = f.read() print(res.decode('utf-8')) # 这里本来输出的是二进制,需要decode进行解码 # 例题:文件拷贝 # 方法一: with open('1.mp4',mode='rb') as f1,\ open('D:\111.mp4',mode='wb') as f2: res = f1.read() # 将整个文件内容读出 print(write(res) # 方法二: with open('1.mp4',mode='rb') as f1,\ open('D:\111.mp4',mode='wb') as f2: for line in f1: # 循环遍历,一行一行读出 f2.write(line) # 了解 可读可写 # r+t # w+t # a+t # r+b # w+b # a+b # with open('a.txt',mode='r+t',encoding='utf-8') as f: # print(f.readable()) # print(f.writable()) # print(f.read()) # f.write("22222222222222222222\n") # with open('a.txt',mode='w+t',encoding='utf-8') as f: # print(f.readable()) # print(f.writable())
-
-
操作文件的方法
# 重点 # 1.读操作 # f.read() # 读取所有内容,执行完该操作后,指针移至文件末尾 # f.readline() # 读取一行内容,指针移至第二行内容开头 # f.readlines() # 读取每一行内容,存放于列表中 # 强调:f.read()和f.readlines()都是一次性读入内容,如果内容过大,会导致内存溢出, # 如果想将内容全部读入内存,必须分多次读入,一下有两种方式 # 方法一: with open('a.txt',mode='rt',encoding='utf-8') as f: for line in f: print(line) # 同一时刻只将一行代码读入内存 # 方法二: with open('1.mp4',mode='rb') as f: while True: res = f.read(1024) # 同一时刻只读入1024个bytes到内存中 if len(res) == 0: break print(res) # 2.写操作 # f.write('111\n222\n') # 针对文本模式的写 # f.write('111\n222\n'.encode('utf-8')) # 针对b模式的写 同时这里本来输出的是二进制,需要encode进行解码 # f.writelines(['111\n','222\n']) # 针对文件模式 ,且这里用列表形式输出 # f.writelines([bytes('111\n',encode='utf-8'),'222\n'.encode('utf-8')]) # 针对b模式 # 注:这里用了两种方式: 1、bytes('111\n',encode='utf-8') 2、'222\n'.encode('utf-8') # 了解 f.readable() # 文件是否可读 f.writable() # 文件是否可读 f.closed # 文件是否关闭 f.encoding # 如果文件打开模式为b,则没有该属性 f.flush() # 立刻将文件内容从内存刷到硬盘 f.name -
主动控制文件内指针移动
# 文件指针的移动都是bytes为单位的,唯一例外的是t模式下的read(n),n以字符为单位,一个字符=3bytes with open('a.txt',mode='rt',encode='utf-8') as f: f.read(3) # 读取3个字符 with open('a,txt',mode='rb') as f: f.read(3) # 读取3个bytes # 若想读取文件某一特定位置的数据,可用f.seek()主动控制文件内指针的移动 # f.seek(指针移动的字节数,模式控制) # 模式控制(0,1,2三种模式) # 0:该模式代表指针移动的字节数是以文件开头为参照的(默认模式) # 1:该模式代表指针移动的字节数是以当前所在位置为参照的 # 2:该模式代表指针移动的字节数是以文件结尾为参照的 # 0模式: # hello你好 # with open('a.txt',mode='rt',encoding='utf-8') as f: # f.seek(3,0) # print(f.tell()) # 查看当前文件指针距离文件开头的位置 3 # print(f.read()) # 从第三个字节读到文件末尾 lo你好 # with open('a.txt',mode='rt',encoding='utf-8') as f: # f.seek(6,0) # print(f.tell()) # 查看当前文件指针距离文件开头的位置 6 # print(f.read()) # 从第三个字节读到文件末尾 报错 # 这里报错,因为在t模式下会将读取的内容自动解码, # 所以必须保证读取的内容是一个完整的中文数据,否则解码失败报错 # 1模式 # 123456789 # with open('d.txt',mode='rb') as f: # f.seek(3,1) # 从当前位置往后移动3个字节,而此时的当前位置就是文件开头 # print(f.tell()) # 查看当前文件指针距离文件开头的位置 3 # print(f.read()) # b'456789' # f.seek(4,1) # 再次从当前位置往后移动3个自己,而此时的文件指针位置在9后面 # print(f.tell()) # 9再往后4个bytes,位置为13 # print(f.read()) # 此时内容为 b'' # 2模式 # abc你好 # with open('a.txt',mode='rb') as f: # f.seek(0,2) # 参照文件末尾移动0个字节, 即直接跳到文件末尾 # print(f.tell()) # 输出结果为:9 # f.seek(-3,2) # 参照文件末尾往前移动了3个字节 # print(f.read().decode('utf-8')) # 输出结果为:好 -
文件修改
''' 1.硬盘的空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容 2.内存中的数据是可以修改的 ''' # 原内容 # ycc 江苏 180 1001 # xix 江苏 165 1002 # haha 上海 170 1003 # with open('d.txt',mode='r+t') as f: # f.seek(3) # f.write('aaa') # 输出结果: # yccaaa 江苏 180 1001 # xix 江苏 165 1002 # haha 上海 170 1003 # 这里只是覆盖硬盘里的内容,并没有修改 # 修改方式一: # 将文件一次性全部读入内存,在内存中将文件内容进行修改,再用w模式,将之前的文件清空,将现文件写入 # 优点:在文件修改过程中同一份数据只有一份 # 缺点:会过多的占用内存 # with open('e.txt', mode='rt', encoding='utf-8') as f: # res = f.read() # with open('e.txt', mode='wt', encoding='utf-8') as f: # f.write(res.replace('ycc', 'xixi')) # 修改方式二: # 以读的方式打开一个文件,以写的方式打开一个临时文件,用for循环遍历读取每一行的内容, # 修改完后写入临时文件,删除原文件,将临时文件重命名 # 优点:不会占有过多内存 # 缺点:在文件修改的过程中同一数据存了2份 # import os # # with open('e.txt', mode='rt', encoding='utf-8') as read_f, \ # open('f.txt', mode='wt', encoding='utf-8') as write_f: # for line in read_f: # write_f.write(line.replace('xixi', 'ycc')) # os.remove('e.txt') # os.rename('f.txt', 'e.txt')

浙公网安备 33010602011771号