【Python基础】文件操作
文件操作
计算机系统分为:计算机硬件,操作系统,应用程序三部分。
我们用Python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作
硬件,众所周知,应用程序是无法直接操作硬件的,这就用到了操作系统。操作系统把复杂的硬件操作封装成简单的接口给用
户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的
数据永久保存下来。有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程:
#1. 打开文件,得到文件句柄并赋值给一个变量
#2. 通过句柄对文件进行操作
#3. 关闭文件
文件 读 r 操作
f=open('陈粒',encoding='utf-8') data=f.read() print(data) f.close() f=open('xxx') data=f.read() print(data) f=open('陈粒','r',encoding='utf-8') data=f.read() # print(data) print(f.readable()) print('第1行',f.readline(),end='') print('第2行',f.readline()) print('第3行',f.readline()) # for i in range(1): # pass print('第4行',f.readline()) print('第5行',f.readline()) print('第6行',f.readline()) print('第7行',f.readline()) data=f.readlines() print(data) f.close()
文件 写 w 操作
f=open('陈粒1','w',encoding='utf8') # f.read() f.write('11111111\n') f.write('222222222\n') f.write('333\n4444\n555\n') # f.writable() f.writelines(['555\n','6666\n']) f.writelines(['555\n','6666\n',1]) # 文件内容只能是字符串,只能写字符串 f.close()
文件 追加 a 操作
f=open('陈粒1','a',encoding='utf-8') f.write('追加方式写到文件最后')
"+" 表示可以同时读写某个文件
r+, 读写【可读,可写】
w+,写读【可读,可写】
a+, 写读【可读,可写】
文件修改
src_f=open('xxx','r',encoding='gbk') data=src_f.readlines() src_f.close() # for i in data: # print(i) print(data) dst_f=open('xxx','w',encoding='gbk') # dst_f.writelines(data) dst_f.write(data[0]) dst_f.close() with open('a.txt','w') as f: f.write('1111\n') src_f=open('xxx','r',encoding='gbk') dst_f=open('xxx','w',encoding='gbk')
推荐-以 with 方式打开多个文件
with open('xxx','r',encoding='gbk') as src_f,\ open('xxx_new','w',encoding='gbk') as dst_f: data=src_f.read() dst_f.write(data) f=open('a.txt') print(f.encoding) #查看文件编码
with open('a.txt','r',encoding='utf8') as fa: for row in fa: #fa获得多行数据组成的列表
print(row.strip())
以 bytes(二进制)方式打开文件(主要是视频、音频文件)
f=open('test11.py','rb',encoding='utf-8') #b的方式不能指定编码 f=open('test11.py','rb') #b的方式不能指定编码 data=f.read() #'字符串'---------encode---------》bytes #bytes---------decode---------》'字符串' print(data) print(data.decode('utf-8')) f.close() f=open('test22.py','wb') #b的方式不能指定编码 f.write(bytes('1111\n',encoding='utf-8')) f.write('中国'.encode('utf-8')) f=open('test22.py','ab') #b的方式不能指定编码 f.write('中国'.encode('utf-8')) open('a.ltxt','wt')
补充:需求:读取几万行日志文件的最后一行
f.readlines() 直接全部读出来放在内存中 很耗内存空间
# f=open('日志文件','rb') # data=f.readlines() # print(data[-1].decode('utf-8')) f=open('日志文件','rb') # for i in f.readlines(): # print(i) #循环文件的推荐方式,以行为单位读取,取一行用一行 不全部放在内存中 # for i in f: # print(i) for i in f: offs=-10 while True: f.seek(offs,2) data=f.readlines() if len(data) > 1: print('文件的最后一行是%s' %(data[-1].decode('utf-8'))) break offs*=2
###操作文件的一些方法总结
#掌握 f.read() #读取所有内容,光标移动到文件末尾 f.readline() #读取一行内容,光标移动到第二行首部 f.readlines() #读取每一行内容,存放于列表中 f.write('1111\n222\n') #针对文本模式的写,需要自己写换行符 f.write('1111\n222\n'.encode('utf-8')) #针对b模式的写,需要自己写换行符 f.writelines(['333\n','444\n']) #文件模式 f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式 #了解 f.readable() #文件是否可读 f.writable() #文件是否可读 f.closed #文件是否关闭 f.encoding #如果文件打开模式为b,则没有该属性 f.flush() #立刻将文件内容从内存刷到硬盘 f.name
"""
练习,利用b模式,编写一个cp工具,要求如下:
1. 既可以拷贝文本又可以拷贝视频,图片等文件
2. 用户一旦参数错误,打印命令的正确使用方法,如usage: cp source_file target_file
提示:可以用import sys,然后用sys.argv获取脚本后面跟的参数
使用cmd命令行执行test1.py 后面可以跟上参数,用sys.argv获取参数列表[test1.py,arg1,arg2...]
"""
import sys if len(sys.argv) != 3: print('usage: cp source_file target_file') sys.exit() print(sys.argv) #['test1.py', 'aa.txt', 'bb'] source_file,target_file=sys.argv[1],sys.argv[2] with open(source_file,'rb') as read_f,open(target_file,'wb') as write_f: for line in read_f: write_f.write(line)
文件内光标移动
一: read(3):
1. 文件打开方式为文本模式时,代表读取3个字符
2. 文件打开方式为b模式时,代表读取3个字节
二: 其余的文件内光标移动都是以字节为单位如seek,tell,truncate
注意:
1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
文件的修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)
import os with open('./a.txt','r') as read_f,open('./newa.txt','w') as write_f: data=read_f.read() #全部读入内存,如果文件很大,会很卡 data=data.replace('alex','SB') #在内存中完成修改 write_f.write(data) #一次性写入新文件 os.remove('./a.txt') os.rename('./newa.txt','a.txt')
方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件
import os with open('./a.txt') as read_f,open('./newa.txt','w') as write_f: for line in read_f: line=line.replace('alex','SB') write_f.write(line) os.remove('./a.txt') os.rename('./a.txt','./a.txt')
案例:在文件中查询内容
"""实现在文件中 查询某一行打印出这行下级的内容""" def fetch(data): backend_data = "backend %s"%data with open('haproxy.conf','r') as read_f: tag = False res = [] for read_line in read_f: if read_line.strip() == backend_data: tag = True continue if tag and read_line.startswith("backend"): break if tag and read_line.strip() is not None: print(read_line.strip()) res.append(read_line.strip()) return res def add(): pass def change(): pass def delete(): pass if __name__ == '__main__': msg = ''' 1:查询 2:添加 3:修改 4:删除 5:退出 ''' msg_dic = { '1': fetch, '2': add, '3': change, '4': delete, } while True: print(msg) choice = input("输入你的选项>>>").strip() if not choice:continue if choice =="5":break data = input("输入你的数据>>>").strip() res = msg_dic[choice](data) #res 是所选择函数的返回值 print(res)
补充知识:多层while循环嵌套时 如何跳出?
"""输入一个quit_all 退出所有while层的循环""" tag=True while tag: print('leve1') choice=input("level1>>: ").strip() if choice == 'quit':break if choice == 'quit_all': tag = False while tag: print('level2') choice = input("level2>>: ").strip() if choice == 'quit': break if choice == 'quit_all': tag = False while tag: print('level3') choice = input("level3>: ").strip() if choice == 'quit': break if choice == 'quit_all': tag = False
文件/文件夹操作参考 os模块
# import os # # os.rename('a.txt','a.txt.bak') # os.rename('b.txt','aa.py') #rename 修改文件或文件夹名称(或类型)
参考:http://www.cnblogs.com/linhaifeng/articles/5984922.html#_label28