五.python文件处理
1.什么是文件
- 定义:在python中常指的文件为计算机文件,计算机文件是以计算机硬盘为载体存储在计算机上的信息集合。
- 文件的特征:
1.可读
2.可写
3.可修改
2.文件操作的过程
2.1 基本操作语法及规则
- 语法:文件 = open('文件路径',encoding = '编码类型','模式')
- 不指定打开编码,默认使用操作系统的编码,windows为gbk,linux为utf-8,与解释器编码无关
打开文件的模式:
- r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】
- w,只写模式【不可读;不存在则创建;存在则清空内容】
- x, 只写模式【不可读;不存在则创建,存在则报错】
- a, 追加模式【可读; 不存在则创建;存在则只追加内容】
"+" 表示可以同时读写某个文件
- r+, 读写【可读,可写】
- w+,写读【可读,可写】
- x+ ,写读【可读,可写】
- a+, 写读【可读,可写】
"b"表示以字节的方式操作
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码
2.2 文件读操作
1 #指定编码: 2 如果不指定编码,默认根据操作系统编码来读,windows为gbk,linux为utf-8 3 4 # read一次读取全部 5 f=open('test','r',encoding='utf-8') 6 data = f.read() 7 print(data) 8 f.close() #文件操作完一定要关闭。 9 10 # readline一次读一行 11 f=open('test','r',encoding='utf-8') 12 print(f.readline(),end='') #读第一行,end=''可以取消print的自动换行 13 print(f.readline(),end='') #读第二行 14 print(f.readline(),end='') #读第三行 15 f.close() 16 17 #readable判断文件是否可读,可读返回True,不可读返回False 18 f=open('test','r',encoding='utf-8') 19 data = f.readable() 20 print(data) 21 f.close() #文件操作完一定要关闭。 22 23 #readlines全部读出来,放到列表里 24 f=open('test','r',encoding='utf-8') 25 data = f.readlines() 26 print(data) #这里的data为一个大列表 27 f.close() #文件操作完一定要关闭。
2.3 文件写操作
1 #w,写模式,文件不存在会创建,存在会清空打开 ***** 2 f=open('test','w',encoding='utf-8') 3 f.write('11111111111\n') #基本写入 4 f.write('222222222222\n') 5 f.write('3333\n4444444\n') 6 f.writelines(['777\n','888\n','999\n']) #writelines写入一个列表 7 #f.write(1) #写文件只能是字符串,不能是数字 8 #print(f.writable()) #判断文件是否可写 9 f.close()
2.4 文件追加操作
1 #a模式,追加文件,文件存在则追加,不存在则创建 2 f=open('test','a',encoding='utf-8') 3 f.write('\n') 4 f.write('#'*30) #在文件最后一个字符后追加,默认是不换行追加 5 f.write('\n') 6 f.close()
2.5 文件处理其他操作
1 # r+ 读写操作,即可读,又可写 2 f=open('test','r+',encoding='utf-8') 3 # f.read() 4 f.write("zhangsan") #文件打开直接就写,会覆盖文件开头,写多少字符覆盖多少字符*** 5 f.close() 6 7 # w+ 写读操作,即可写,又可读,w+特点和w类似,文件不存在会常见,存在会清空打开 ***** 8 f=open('test','w+',encoding='utf-8') #w+和w唯一的区别是可以读。 9 # f.read() 10 f.write('11111111111\n') 11 f.close() 12 13 # a+ 写读操作,即可写,又可读,和a的区别是a+可以读。 14 f=open('test','a+',encoding='utf-8') 15 #f.read() 16 f.write('#'*30) 17 f.write('\n') 18 f.close() 19 20 # 文件修改,严格意义上讲,文件没有修改的操作,一般修改原理是从源文件读,往目标文件写,再用这个目标文件覆盖源文件以达到修改的效果。 21 # 基本原理 22 src_f = open('test','r',encoding='utf-8') 23 data = src_f.readlines() 24 src_f.close() 25 26 dst_f = open('test','w',encoding='utf-8') 27 dst_f.writelines(data[0]) 28 dst_f.close() 29 30 #with open 每次打开文件都要关闭,有时候会忘记,with open会自动关闭文件。 31 # with open拷贝 32 with open('test','r+',encoding='utf-8') as src_f,\ 33 open('test1','w',encoding='utf-8') as dst_f: 34 data = src_f.readlines() 35 print(data) 36 dst_f.writelines(data[0]) 37 38 #rb 二进制读,这里不指定编码,是因为要求是以二进制的方式读取,硬盘上存的文件是二进制,open打开其实是把二进制放到内存中,指定编码的意思是,打开文件让我们能看得懂,二进制b代表的是字节,按照字节读取。 39 40 想要看到读到的内容 41 #字符串----------encode----------->bytes(硬盘) 字符串通过encode存到硬盘,编码形式 42 #bytes-----------decode----------->字符串 硬盘通过decode转换为字符串,解码形式 43 44 f = open('test','rb') 45 data = f.read() 46 print(data) #输入会有换行符,\r\n是window的换行符,\n是linux的换行符 47 f.close() 48 49 #wb 二进制写,如下要进行编码然才能在到到硬盘,bytes是指定字符串编码,不指定编码一定不能存到硬盘 *** 50 51 f = open('test22','wb') #b的方式不能指定编码 52 # f.write('111111\n') #报错TypeError: a bytes-like object is required, not 'str' 53 f.write(bytes('11111\n',encoding='utf-8')) #第一种方法 54 f.write('222222\n'.encode('utf-8')) #第二种方法 55 f.close() 56 57 #######其他方法########## 58 #latin-1解决乱码问题, 59 f = open('a.txt','w',encoding='latin-1') #latin-1:如果不知道文件是什么编码,latin-1可以把大部分吸纳出来,遇到问题,可以试试。 60 #看文件是否已经关闭 61 print(f.closed) 62 #取的是文件打开的编码 63 print(f.encoding) 64 #内存的东西刷新到硬盘上,默认python会每隔固定间隔写到硬盘 65 f.flush() 66 #取光标现在所在的位置 67 f.tell() 68 69 #windows系统默认是\r\n,不指定newline,python会自动把\r\n统一转换为\n 70 f = open('a.txt','w',encoding='latin-1',newline='') 71 #移动光标所在的位置,按照‘字节’移动 72 f.seek() 73 #读文件,按照“字符”来读 74 f.read() 75 #文件截断 ,开头截取10个字节,其他的全删除。 76 f.truncate(10) 77 78 #######seek高级玩法########## 79 80 f = open('seek.txt','rb') 81 print(f.tell()) 82 f.seek(1) 83 print(f.tell()) 84 f.seek(3) #等于3,从头开始算,绝对路径来算 85 print(f.tell()) 86 f.seek(5,1) #1代表从上一个开始算,相对路径 87 print(f.tell()) 88 f.seek(-3,2) #2代表倒着读,但第一个参数必须是负数 89 print(f.read()) 90 print(f.tell()) 91 f.seek(-5,2) #相对路径倒着读(倒着读用途是在日志处理,从后面读,减少服务器压力) 92 print(f.tell()) 93 94 95 #######读文件优化########## 96 for i in f.readlines(): #这种方式效率不高,内存占用较大,所有东西读出来,再循环 97 print(i) 98 99 #优化(这种方式是,f是文件句柄,读一条看一条,内存占用小) 100 for i in f: 101 print(i) 102 103 #文件倒序读取,有些时候,类似于日志的大文件,开头对于我们来说并不重要,末尾几天的日志对我们来说有时候很重要,这个时候就可以倒叙读文件,优点是减轻服务的压力 104 #方法(比如读取文件最后一行): 105 f = open('seek.txt','rb') 106 for i in f: 107 #倒着seek 108 offs=-2 # 定义一个阀值,循环阀值,当取到最后一行的时候结束。实际用的时候估算下一行多少字节,尽量循环次数减少 109 while True: 110 f.seek(offs,2) 111 data = f.readlines() #这里的readlines并不是读取文件所有,而是读取seek那一段的一行 112 if len(data) > 1: 113 print('文件最后一行是%s' %(data[-1].decode('utf-8'))) 114 break 115 offs*=2 #如果不满足一行就把阀值乘以2,生产环境可以自定义调节