文件操作
对文件的操作流程
1、打开文件,得到文件句柄(作用就好像锅把手)并赋值给一个变量
2、通过句柄对文件进行操作
3、关闭文件
即:1、打开文件 open()
2、操作文件 read()write()
data=f.read(5)#5指的是指定个数的字符,从光标所在位置算起
data=f.readlines()#拿到列表结果,带换行符从光标所在位置算起
3、关闭文件 close()
注意如果在Windows系统中,hello文件是utf8保存的,打开文件时open函数是通过操作系统打开的文件,而Windows操作系统默认的是gbk编码,所以直接打开会乱码,需要f=open('hello',encoding='utf8'),hello文件如果是gbk保存的,则直接打开即可。
4、读操作(r)写操作(w,r)都是对字符进行操作
#r读操作
f = open("test",encoding="utf-8") #打开文件 data = f.read()#获取文件内容 print(data) data = f.readlines() f.close()#关闭文件 #在print中加入东西的加入东西的两种方法,文件本身没有改变 count = 0 for line in f.readlines(): if count == 3: line="".join([line.strip(),"岳飞"]) print(line.strip()) count+=1 count=0 for line in f: if count == 2 : line = "".join([line.strip(),"sdf"]) print(line.strip()) count+=1
#w,写操作,覆盖加 f = open("test",mode="w",encoding="utf-8") #打开文件 f.write("hello")#覆盖写,把原来的东西覆盖掉 f.write("hello\nworld")#在文件没有关闭之前,可以可以继续追加 #a,写操作,追加 f = open("test",mode="w",encoding="utf-8") f.write("hello")#追加写,在原来的东西后面写
5、flush操作(进度条)
flush是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法。
#语法 f.write("hello tests") f.flush()#用于做进度条 #进度条简单版 import sys for i in range(100): sys.stdout.write("#")#是一个文件,相当于屏幕,平时用到的print就是用stdout写的 sys.stdout.flush() import time time.sleep(0.5)
#进度条优化版 import sys for i in range(100): s="\r%d%% %s"%(i,"#"*i) #"#"后边乘以3代表"###",这也是一种拼接方式 sys.stdout.write(s) #\r表示让光标回到行的开头 sys.stdout.flush() import time time.sleep(0.5)
6、可读可写模式:r+,w+,a+
#r+ f=open("test","r+",encoding="utf-8") print(f.read()) f.write("where is xialv?")#不管光标位置,一定是追加写 #w+ f=open("test","w+",encoding="utf-8") print(f.read())#什么都读不到,因为首先会覆盖,读的时候一定要记住光标的位置 f.write("where is xialv?") f.seek(0)#将光标移到开始位置,参数是按字节,字节,字节,read的参数是字符 print(f.read()) print(f.tell())#tell是用来查看当前光标的位置,seek是用来调光标位置的,tell参数也是字节 #a+ f=open("test","a+",encoding="utf-8") print(f.read())#读不到,他一开始光标就默认在最后 f.write("where is xialv?")#a+默认追加到最后
7、seek的应用
seek就是移动光标,如上边所给的例子,可以用于断点续传,但是只是知道
#w+和a+,需要通过seek读 12.08
8、rb,wb,ab,针对二进制操作
f=open("test","rb") print(f.read())#看见的都是bytes,字节数据 f=open("test","wb") print(f.read())#看见的都是bytes,字节数据 f=open("test","ab") print(f.read())#看见的都是bytes,字节数据
9、with语句
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
1
2
|
with open ( 'log' , 'r' ) as f: pass |
如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
在Python 2.7 后,with又支持同时对多个文件的上下文进行管理,即:
1
2
|
with open ( 'log1' ) as obj1, open ( 'log2' ) as obj2: pass |
10、文件修改的实质
文件本身是无法修改的,所以我们要打开两个文件一个读(r文件),一个写(w文件),遍历原来的文件,如果不是我想处理的行就直接写入w文件,如果是拿出来对该行(字符串)进行修改,然后在改名字,把这个新的生成的文件当做修改的文件
对文件test进行修改,test内容如下: 昨夜寒蛩不住鸣。 惊回千里梦,已三更。 起来独自绕阶行。 人悄悄,帘外月胧明。 白首为功名,旧山松竹老,阻归程。 欲将心事付瑶琴。 知音少,弦断有谁听。 要求:在第四行后面加一个 岳飞 with open("test",encoding="utf-8")as f_read,open("test7",encoding="utf-8",mode="w")as f_write: count=0 for line in f_read: if count==3: line="".join([line.strip(),"岳飞\n"]) f_write.write(line) count+=1 import os os.rename("test","test_bak") os.rename("test7',"test")
Python中的seek和tell
2. 语法格式: file.tell() 注: 此方法没有参数
--> offset: 偏移量,需要向前或者是向后移动的字节数--> whence: 可选值,默认为0, 可选值为1或者2,表示从何处开始计算偏移,具体来说,
--> 0表示从当前位置开始计算偏移--> 1表示从文件头位置开始计算偏移--> 2表示从文件尾开始计算偏移
>>> x = file('my.log', 'r') #读取一个文件 >>> x.tell() #获得当前文件读取指针 0L #当前文件指针在文件头处 >>> x.seek(3) #将文件指针向文件末尾移动3个字节 >>> x.tell() 3L #指针已经移动到了第3个字节处 >>> x.seek(5,1) #表示从文件头处开始移动指针,向前移动5个字节 >>> x.tell() 5L #当前文件读取指针已经移动到第5个字节处 >>> x.seek(0,0) #表示将文件指针移动到文件头处 >>> x.tell() 0L >>> x.seek(0,2) #表示将文件读取指针移动到文件尾部 >>> x.tell() 214L #可以得到文件大小为214B >>> x.seek(-2,2) #表示从文件尾部开始移动指针,向文件头部移动2个字节 >>> x.tell() 212L