一、文件操作简介
计算机系统分为:计算机硬件,操作系统,应用程序三部分。
我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所周知,应用程序是无法直接操作硬件的,这就用到了操作系统。操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的数据永久保存下来。
有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程:
open函数中模式参数的常用值:
open('文件路径') 默认的打开方式‘r’,默认的打开的编码是操作系统的默认编码
r :读模式
w :写模式
a :追加模式
b :二进制模式(可添加到其他模式中使用)
+ :读/写模式((可添加到其他模式中使用)
备注:
1)一般来说,python默认处理的是文本文件。但是处理一些其他类型的文件(二进制文件),比如声音剪辑或者图像,那么可以使用‘b’模式来改变处理文件的方法。参数‘rb’可以用来读取一个二进制文件。
2)在实际工作过程中,很少遇到又读又写的事情,尽量不要使用‘+’模式,在python3里的文件指针非常乱,读写的时候占用两个不同的指针,所以很容易产生问题
文件操作过程:
1 #1.打开文件,得到文件句柄并赋值给一个变量
2 f1=open(r'C:\a.txt',encoding='utf-8',mode='r')#开头‘r’代表元素字符串的意思,代表‘\’
3 #2.通过句柄对文件进行操作
4 data=f1.read()
5 #3.关闭文件
6 f1.close()
7 #f1为python的变量,保存的文件内容,程序结束才能又python自动回收,文件关闭后不能在对文件进行读写
8 #f1为文件句柄或文件对象,可以设置变量名:file,f_handle,file_handle,f_obj
9 #open():打开的指令,windows的指令
10 #close():关闭文件,回收操作系统资源(不关闭会在内存中一直存在,切记)
11 #windows 的默认编码方式gbk,linux默认编码方式utf-8,max系统为utf-8
二、文件的读
1 # pycharm 创建的文件默认都是utf-8 notepad++默认也是utf-8,但是可以修改编码方式,在格式菜单下修改
2 # EncodeDecodeErrot:编码错误
3 # 读操作:r模式:默认是rt文本读
4 # rb模式:二进制模式,非文字类的文件操作
5 f1=open(r'register',encoding='utf-8')#不写mode,默认以读的形式打开
6 print(f1.read())
7 f1.close()
1、read() 文件内容全部读出
read() 不传参数 意味着读所有
传参,如果是r方式打开的,参数指的是读多少个字符
传参,如果是rb方式打开的,参数指的是读多少个字节
1 f1=open(r'a.txt',mode='rb')#rb模式不用写encoding,它是以bytes类型进行读取
2 data1=f1.read()
3 print(data1)
4 data2=f1.read()#因为读文件有光标移动,第一次读之后,光标移动到最后,第二次读的时候读不到任何内容
5 print(data2)
6 f1.close()
7
8 #read(n) r模式,按照字符读取 ; rb模式,按照字节读取
9 f1=open(r'a.txt',encoding='utf-8')
10 print(f1.read(5))#r模式,按照字符读取
11 f1.close()
12 f1=open(r'a.txt',mode='rb')
13 print(f1.read(3))#rb模式,按照字节读取
14 f1.close()
15
16 # unicode - --> bytes encode()
17 # bytes - --> unicode decode()
18 f1=open(r'a.txt',mode='rb')
19 data=f1.read(3)#写2个字节报错,必须与中文对应位数
20 print(data.decode('utf-8'))#rb模式,按照字节读取
21 f1.close()
2、readline() 按行读取
readline() 一行一行读 每次只读一行,不会自动停止
1 f1=open(r'a.txt',encoding='utf-8',mode='r')
2 print(f1.readline(),end='')#end可以取消print的换行效果
3 print(f1.readline(),end='')
4 f1.close()
3、readlines() 将每一行作为列表的元素,并返回这个列表(不常用)
1 readlines() 将每一行作为列表的元素,并返回这个列表
2 # 在文件比较小的时候可以用read和readlines读取,文件过大时,不建议使用这两种方式
3 f1=open(r'a.txt',mode='rb')
4 print(f1.readlines())
5 f1.close()
4、for 循环
for循环 一行一行读 从第一行开始 每次读一行 读到没有之后就停止
1 f1=open(r'a.txt',mode='rb')#f1这个文件句柄是迭代器,在内存当中只占一行的内存,for循环读取时,永远只在内存当中占一行
2 for line in f1:
3 print(line)
4 f1.close()
5、while 循环 不建议使用
1 with open(b'a.txt','r',encoding='utf-8') as f:
2 while True:
3 line=f.readline()
4 if len(line)==0:break
5 print(line)
三、文件的写
写操作:只能写字符串格式的,不能写数字
w模式:默认是wt文本写,如果文件不存在创建,存在则清空+覆盖
1、write()
1 f=open('a.txt','w',encoding='utf-8')
2 f.write('11111\n')
3 f.write('22222\n')
4 f.close()
2、writelines()
1 f=open('a.txt','w',encoding='utf-8')
2 f.writelines(['哈哈哈\n','hello','world'])
3 f.close()
3、writable 判断文件是否可写
1 f=open('a.txt','w',encoding='utf-8')
2 print(f.writable())#>>>True
3 f.close()
4、a模式 文件不存在则创建,文件存在在打开文件后则光标移动到文件末尾追加写
1 f=open('a.txt','a',encoding='utf-8')
2 f.write('sssss\n')
3 f.close()
5、b模式
1 #b模式 bytes 可以读文本、图片、视频,文件不存在报错
2 #rb模式不能指定字符编码,否则报错
3 with open(b'1.bmp','rb') as f:
4 print(f.read())#输出图片的二进制编码
5 with open(b'a.txt','rb') as f:
6 print(f.read().decode('utf-8'))
7
8 #rt 以文本形式读取
9 with open(b'a.txt','rt',encoding='utf-8') as f:
10 print(f.read())
11
12 #wb
13 with open(b'a.txt','wb') as f:
14 res='你好'.encode('utf-8')
15 print(res,type(res))
16 f.write(res)
17
18 #ab 追加写
19 with open(b'a.txt','ab') as f:
20 res='你好'.encode('utf-8')
21 print(res,type(res))
22 f.write(res)
6、copy
1 #1、源文件大小的问题,一行一行读
2 #2、文件打开模式的问题
3 #flush()方法是用来刷新缓冲器的,即将缓冲区的数据立刻写入文件,同时清空缓冲区,不需要时被动的等待输入,
#一般情况下,文件关闭后会自动刷新缓冲区,但是有时你需要在关闭前刷新它,这时就可以使用flush()方法
4 with open(b'a.txt','rb') as read_f,\
5 open('dstfile','wb') as write_f:
6 for line in read_f:
7 write_f.write(line)
8 # write_f.flush()
9
10 #导入模块的好处就是可以把别人写的功能直接拿来用
11 #sys.argv是用来获取命令行参数的,sys.argv[0]表示代码本身路径,所以参数从1开始
12 import sys
13 _,src_file,dst_file=sys.argv
14 with open(src_file,'rb') as read_f,\
15 open(dst_file,'wb') as write_f:
16 for line in read_f:
17 write_f.write(line)
18 # write_f.flush()
19
20 # encoding:utf-8
21 with open('a.txt','rt',encoding='utf-8') as f:
22 print(f.read())
23
24 # with 程序运行完毕后自动关闭文件
25 with open(r'register',mode='rb') as f1:
26 pass
27 # with open() as 自动关闭文件句柄 同一个with可以操作多个文件句柄
四、文件修改
1 #文件修改
2 #1,打开原文件,产生文件句柄
3 #2,创建新文件,产生文件句柄
4 #3,读取原文件,进行修改,写入新文件
5 #4,将源文件删除
6 #5,新文件重命名原文件
7 import os
8 with open('info.txt','rt',encoding='utf-8') as read_f,open('.info.txt.swap','w',encoding='utf-8') as write_f:
9 data=read_f.read()
10 write_f.write(data.replace('你好','hello'))
11 print(data)
12 os.remove('info.txt')
13 os.rename('.info.txt.swap','info.txt')
14
15 import os
16 with open('info.txt','rt',encoding='utf-8') as read_f,open('.info.txt.swap','w',encoding='utf-8') as write_f:
17 for line in read_f:
18 if '你好' in line:
19 line=line.replace('你好','hello')
20 write_f.write(line)
21 os.remove('info.txt')
22 os.rename('.info.txt.swap','info.txt')
五、文件内光标移动
1 # tell()光标当前的位置(字节)
2 with open('a.txt','r',encoding='utf-8') as f:
3 data1=f.read()
4 print(f.tell())
5
6 #只有一种情况光标以字符为单位,文件以rt方式打开,read(3)
7 with open('a.txt','rt',encoding='utf-8') as f:
8 print(f.read(6))
9 print(f.tell())
10
11 #seek() 光标移动 按照字节去调整
12 with open('a.txt','rt',encoding='utf-8') as f:
13 print(f.read(6))
14 print(f.tell())
15 f.seek(0)
16 print(f.read(6))
17
18 #seek(参数)另外两种模式需要在bytes模式下移动
19 #0模式 可以在t模式下使用
20 #1模式 相对位置移动
21 #2模式 以文件末尾为参照物移动 seek(0,2),调至最后
22 with open('a.txt','rb') as f:
23 f.seek(6,0)
24 print(f.read(6))#>>>b'\xbd\xa0\xe5\xa5\xbd'
25
26 with open('a.txt','rb') as f:
27 print(f.read(6))
28 f.seek(2,1)
29 print(f.tell())
30 print(f.read().decode('utf-8'))
31
32 with open('a.txt','rb') as f:
33 f.seek(-3,2)
34 print(f.tell())
35
36 #tail -f access.log 打开文件读最新追加内容
37 import time
38 with open('access.log','rb') as f:
39 f.seek(0,2)
40 while True:
41 line=f.readline()
42 if line:
43 print(line,end='')
44 else:
45 time.sleep(0.05)
46 with open('access.log','a',encoding='utf-8') as f:
47 f.write('aaaaa\n')
48 f.flush()
49
50 import time
51 with open('access.log','rb') as f:
52 f.seek(0,2)
53 while True:
54 line=f.readline()
55 if line:
56 print(line)
57 else:
58 time.sleep(2)
59
60 #截断文件
61 with open('access.log','a',encoding='utf-8') as f:
62 f.truncate(3)#以文件开头为参照物,截断3字节
View Code