Python攻克之路-文件操作
文件操作
一.文件操作的流程
1. 建立文件
2. 建立文件对象,就是打开文件open函数,即打开文件句柄
3.模式操作,如读r,写w
4.调用方法,如read()
5.关闭文件(.close把缓冲区的数据写入到磁盘,即使不手动做,python也会自动执行,前提是程序执行完,但是建议每次都手动加上)
注意:能调用方法的一定是对象,文件也是对象
In [6]: l1=[1,2,3] #对象
In [7]: l1.append('4') #调用的方法
In [8]: l1
Out[8]: [1, 2, 3, '4']
二.文件操作的模式
注:读模式只能读,写模式只能写
[root@zabbix day8]# cat file.txt hello reid
1.读r:
In [15]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [16]: data=f.read(5) ##5显示多少个字符,在Py3中文和英文一样,默认是取所有
In [17]: print(data)
hello
2.写w:先把之前的清空,再写
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file.txt','w') ##对象创建时,就已经把文件内容清空,文件不存在就会创建文件
data=f.write('hello world')
print(data)
f.close()
[root@zabbix day8]# python3 file-operate.py
11
[root@zabbix day8]# cat file.txt
hello world[root@zabbix day8]#
##连续写不换行
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file1.txt','w')
f.write('hello world')
f.write('tom')
f.close()
[root@zabbix day8]# python3 file-operate.py
[root@zabbix day8]# cat file1.txt
hello worldtom[root@zabbix day8]#
分析:文件在内存里,如划分成一行行的,每行里还划分成一个个格,如存一个hello,一个个单位的存储,存完后,如果后面还有存储它就会接着存,不会有任何东西,如果需要空格可以在里面加空格,然后空格就占用一个位置,可以加换行符,如果不加就会走到行的最大量才换.实际上python有一个指针,如在写文件时,都在开始处,如写hell,指针一开始在h,写到l时就停在l,再写其他就从l开始写
f.write('hello world \n')
f.write('tom')

3.追加a:在光标所在处开始追加
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file1.txt','a') ##a追加
f.write('\n hello world \n')
f.write('tom')
f.close()
[root@zabbix day8]# cat file1.txt
hello worldtom[root@zabbix day8]#
[root@zabbix day8]# python3 file-operate.py
[root@zabbix day8]# cat file1.txt
hello worldtom
hello world
4. r+ 读写,光标默认在起始位置,常用的模式***
[root@zabbix day8]# cat file1.txt
hi reid
hello world
In [30]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','r+')
In [31]: print(f.readline())
hi reid
In [32]: f.write('tom')
Out[32]: 3
[root@zabbix day8]# cat file1.txt
hi reid
hello world
tom[root@zabbix day8]#
5. w+ 写读
[root@zabbix day8]# cat file1.txt
hi reid
hello world
In [34]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','w+') ##打开后,就直接格式化之前的内容
In [35]: print(f.readline()) ##直接读时为空
In [36]: f.write('tom') ##写入新内容
Out[36]: 3
In [37]: print(f.tell()) ##写入新内容后光标所在3,再读也是空
3
In [38]: print(f.readline())
In [39]: f.close()
[root@zabbix day8]# cat file1.txt
tom[root@zabbix day8]#
把光标重新移动:
[root@zabbix day8]# cat file1.txt
tom
In [41]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','w+')
In [42]: f.write('reid \n')
Out[42]: 6
In [43]: print(f.readline())
In [44]: f.seek(0)
Out[44]: 0
In [45]: print(f.readline())
reid
In [46]: f.close()
6. a+ 追加可读,光标默认是在最后
[root@zabbix day8]# cat file1.txt
reid
In [47]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','a+')
In [48]: print(f.tell())
6
In [49]: print(f.readline())
三.文件操作具体方法
1.readline按行读
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
print(f.readline())
print(f.readline())
f.close()
[root@zabbix day8]# python3 file-operate.py
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting
2.read按字符读
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
print(f.read(5))
print(f.read(5))
f.close()
[root@zabbix day8]# python3 file-operate.py
I hea 读到5个字符时,还有一个换行符
rd th
3.readlines输出列表
In [1]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [2]: print(f.readlines())
['I heard the echo, from the valleys and the heart\n', 'Open to the lonely soul of sickle harvesting\n', 'Repeat outrightly, but also repeat the well-being of\n', 'Eventually swaying in the desert oasis\n']
4.使用for循环使用readlines直接读列表里的内容
In [3]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [4]: for i in f.readlines():
...: print(i)
...:
I heard the echo, from the valleys and the heart ##打印时本身就有一个换行,再加print默认有个换行
Open to the lonely soul of sickle harvesting
Repeat outrightly, but also repeat the well-being of
Eventually swaying in the desert oasis
strip()把末尾的换行自动去掉
In [7]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [8]: for i in f.readlines():
...: print(i.strip())
...:
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting
Repeat outrightly, but also repeat the well-being of
Eventually swaying in the desert oasis
5.实现处理文件中某一行,增加一个字符串
#!/usr/local/python3/bin/python3
num=0
f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
for i in f.readlines():
num +=1 ##每读一行就加1
if num == 2: ##读到第2行时就加上需要加的字符串
print(i.strip(),'======reid')
else:
print(i.strip())
f.close()
[root@zabbix day8]# python3 file-operate.py
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting ======reid
Repeat outrightly, but also repeat the well-being of
Eventually swaying in the desert oasis
优化一:
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
num=0
f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
for i in f.readlines():
num +=1
if num == 2:
i='+++++'.join((i.strip(),'reid')) ##直接使用i=,节省了一个Print,字符串拼接时使用join
print(i.strip())
f.close()
[root@zabbix day8]# python3 file-operate.py
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting+++++reid
Repeat outrightly, but also repeat the well-being of
Eventually swaying in the desert oasis
优化二:
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
data=f.readlines()
#只把文件读了一下,把内容取出来,马上就关闭,剩下就自己处理,使用文件的时间短,优化一是整个操作都在文件打开过程中,看实际,如果频繁操作效率不高
f.close
num=0
for i in data:
num +=1
if num == 2:
i='+++++'.join((i.strip(),'reid'))
print(i.strip())
f.close()
[root@zabbix day8]# python3 file-operate.py
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting+++++reid
Repeat outrightly, but also repeat the well-being of
Eventually swaying in the desert oasis
##不使用定义变量:num,使用enumerate来接收两个变量
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
for i,v in enumerate(f.readlines()):
if i == 2:
v=' ******'.join((v.strip(),'reid'))
print(v.strip())
f.close()
[root@zabbix day8]# python3 file-operate.py
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting
Repeat outrightly, but also repeat the well-being of ******reid
Eventually swaying in the desert oasis
优化三:使用列表直接修改
In [9]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [10]: data=f.readlines()
In [11]: data[1]='Open to the lonely soul of sickle harvesting ppppppppppp'
In [12]: print(data)
['I heard the echo, from the valleys and the heart\n', 'Open to the lonely soul of sickle harvesting ppppppppppp', 'Repeat outrightly, but also repeat the well-being of\n', 'Eventually swaying in the desert oasis\n']
优化四: 对readlines的优化方式:**** 推荐用法
注:readlines是把数据都读到内存里,如果文件大的话一下子就会崩溃
In [1]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [2]: for i in f: #文件本身在磁盘上,for i in f时没有对磁盘作任何操作
...: print(i.strip())
##内部,python会对for做了特殊处理,把f做成迭代器,它会用时取一个,不用就不取,对于文件本用一行取一行,数据在磁盘,使用时在内存,使用算法计算实现
...:
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting
Repeat outrightly, but also repeat the well-being of
Eventually swaying in the desert oasi
对某行处理:
[root@zabbix day8]# cat file-operate.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
num=0
for i in f:
num +=1
if num == 2:
i='+++++'.join((i.strip(),'reid'))
print(i.strip())
f.close()
[root@zabbix day8]# python3 file-operate.py
I heard the echo, from the valleys and the heart
Open to the lonely soul of sickle harvesting+++++reid
Repeat outrightly, but also repeat the well-being of
Eventually swaying in the desert oasis
summary: readlines与迭代器对比
readlines: 有一个文件,内容一行行在磁盘里存储着,使用readlines是完全把整个文件copy到内存里,对它进行操作,如果文件的太大就会影响性能
迭代器的实现:做一个迭代器在内存里,当使用第一行内容时,就取第一行的内容,取到放在内容后,可以对它进行应用,如print下,print完后,内存就没有相当于del,是解释器做的,再到下一行,整个处理的过程中只有一行的内容

6.tell: 用于检测当前光标的位置
In [1]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [2]: print(f.tell()) #开始是0
0
In [3]: print(f.read(10))
I heard th
#光标所在的位置,包括空格,在python3里,字符集为utf-8时,英文是1个字母1个字符,一个中文占3个字符,python2是中英一样
In [4]: print(f.tell())
10
7.seek调整光标 ****
使用场景:服务器客户端上传下载,如上传100M的文件,传到50M时断了,使用断点续传时,如果判断到它传了50M,可以使用seek调整到50M的位置
In [5]: f=open('/root/py/fullstack_s2/week2/day8/file.txt','r')
In [6]: print(f.tell())
0
In [7]: print(f.read(2))
I
In [8]: print(f.tell())
2
In [9]: f.seek(0)
Out[9]: 0
In [10]: print(f.tell())
0
8.文件操作之flush
场景分析:当f.write时是没有写到disk,直到f.close后才写到disk,是先写到缓存中,直到满了或者close,如果实时写到disk会影响性能,不过在数据安全性高的场景就需要实时写磁盘,使用flush方法来实现,当write一条数据后,使用flush就会把缓存更新,把数据存放到磁盘上去
In [3]: f=open('test','w')
In [4]: f.write('reid is good')
Out[4]: 12
In [5]: f.write('hello')
Out[5]: 5
[root@zabbix day8]# cat test ##write后并没有写到disk
[root@zabbix day8]#
In [6]: f.flush() ##flush后把缓存的数据写到磁盘上
[root@zabbix day8]# cat test
reid is goodhello[root@zabbix day8]#
flush在进度条的使用
In [7]: import sys,time
In [8]: for i in range(30):
...: sys.stdout.write("*") #sys.stdout终端的输出
...: time.sleep(0.2)
****************************** ##这种情况,它是先写到缓存里,当30个完成写完,0.2*30=6秒钟后才统一显示
实现进度条:
In [9]: for i in range(30):
...: sys.stdout.write("*")
...: sys.stdout.flush() ##加上flush后,就会每0.4秒打印一个*显示在终端
...: time.sleep(0.4)
...:
******************************
另一种方法:
In [13]: for i in range(30):
...: print('*',end='',flush=True) #end等于空不换行,flush作为print的参数立刻刷新
...: time.sleep(0.1)
******************************
9.truncate():截断,取决于光标所在的位置开始截取
追加的情况:
[root@zabbix day8]# cat file1.txt
hello world
In [22]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','a')
In [23]: f.truncate(4)
Out[23]: 4
[root@zabbix day8]# cat file1.txt
hell[root@zabbix day8]#
写的情况:
[root@zabbix day8]# cat file1.txt
hello world
In [24]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','w')
In [25]: f.truncate(4)
Out[25]: 4
[root@zabbix day8]# cat file1.txt
[root@zabbix day8]#
In [26]: f.write('hi reid') ##先写再截取
Out[26]: 7
In [27]: f.truncate(4)
Out[27]: 4
[root@zabbix day8]# cat file1.txt
hi r[root@zabbix day8]#
10.with方法
在退出with语句后,会自动把文件进行关闭,不使用f.close()
In [153]: with open('file1.txt','r') as f:
...: print(f.readline())
...:
I heard the echo
在python2.7后,with可以同时对两个不同的对象操作
In [154]: with open('file1.txt','r') as f_read, open('file2.txt','w') as f_write:
...: for line in f_read:
...: f_write.write(line) ##读file1.txt文件,把每行写入file2.txt中
四.修改文件的思路(*****)
注:r与w的光标是不一致的,r是从起始开始,w写是从最后开始写的
思路一:直接在光标所在的位置修改
[root@zabbix day8]# cat file1.txt
I heard the echo
Open to the lonely
Repeat outrightly
Eventually swaying
In [66]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','r+')
In [67]: num=0
In [68]: for line in f:
...: num+=1
...: if num==3: ###按理论当num==3时,是光标所在行,当时在最后写
...: f.write(' ++++reid')
...: f.close()
[root@zabbix day8]# cat file1.txt
I heard the echo
Open to the lonely
Repeat outrightly
Eventually swaying
++++reid[root@zabbix day8]#
[root@zabbix day8]# cat file1.txt
I heard the echo
Open to the lonely
Repeat outrightly
Eventually swaying
In [69]: f=open('/root/py/fullstack_s2/week2/day8/file1.txt','r+')
In [70]: num=0
In [71]: for line in f:
...: num+=1
...: if num==1: ##当num==1时,还是在最后一行写
...: f.write(' ++++reid')
...: f.close()
[root@zabbix day8]# cat file1.txt
I heard the echo
Open to the lonely
Repeat outrightly
Eventually swaying
++++reid[root@zabbix day8]#
思路二:创建新的文件,把旧文件每个读到一个新文件里,读到某一处理的行时,再处理,新的文件就修改完
注意:
a. 调用read,write的方法时,要是对象,如file文件,字符串不行
b. 创建一个新对象时,不要放进for循环中,否则会产生多个对象
[root@zabbix day8]# cat file1.txt
I heard the echo
Open to the lonely
Repeat outrightly
Eventually swaying
[root@zabbix day8]# cat test.py
#!/usr/local/python3/bin/python3
f=open('/root/py/fullstack_s2/week2/day8/file1.txt','r') ##从一个文件里读
f1=open('/root/py/fullstack_s2/week2/day8/file2.txt','w') ##写入一个新创建的文件
num=0
for line in f:
num+=1
if num==3: ##当光标到第三行时操作
#line='hello reid \n'
line=' '.join([line.strip(),'hello reid \n'])
f1.write(line)
f.close()
f1.close()
[root@zabbix day8]# python3 test.py
[root@zabbix day8]# cat file2.txt
I heard the echo
Open to the lonely
Repeat outrightly hello reid ###
Eventually swaying

浙公网安备 33010602011771号