我们可以知道:
要进行文件读写操作的话,使用open()函数;
要操作文件属性及路径的话,使用os.path模块;
要读取命令行中文件的话,使用fileinput模块;
要操作临时目录或文件的话,使用tempfile模块;
更高级的目录或文件操作,使用shutil模块。
场景一:权限操作
假设输入的路径为:D:\XXX\test\1.txt
import os,statfpath=input(“请输入文件路径:”).strip()#权限更改os.chmod(fpath, stat.S_IREAD) #修改为Windows下只读#os.chmod(fpath, stat.S_IWRITE) #取消Windows下只读#校验权限:是否存在、可读、可写、可执行print(os.access(fpath, os.F_OK)) #Trueprint(os.access(fpath, os.R_OK)) #Trueprint(os.access(fpath, os.W_OK)) #Falseprint(os.access(fpath, os.X_OK)) #True
值得注意的是,os.chxx()形式的API涉及到修改,需要谨慎操作!
场景二:遍历目录/文件 显示文件格式 修改文件名称
假如我想遍历mysql的安装目录,显示每一个文件的格式,并修改某一个文件名称:
分析:
遍历不同深度的目录/文件,需要用到递归算法,这里使用函数的形式表示,为了更直观的展示不同目录下各个文件的格式类型,我准备输出到csv文件进行展示,Demo代码演示:
import os,csv#处理文件类型(非目录)def process_file_type(path, result): #分割输入的路径 split_path = path.split(‘\\’) last = split_path[len(split_path)-1] #修改指定文件名称 if ‘20210611.log’ in last: last = ‘20210611-wxx.txt’ #分割 件名称和后缀 split_hz = last.split(“.”) #右侧起,第一个\的位置,获取文件之前的目录 dir_pos = path.rindex(‘\\’, 0, -1) #将记录行追加到列表中 result.append([path[0:dir_pos 1], split_hz[0], “.” split_hz[len(split_hz)-1]]) #print(“result:” str(result)) return result#遍历目录def find_dir(path, result): #print(“当前dir: ” path) for f in os.listdir(path): #组合新的路径 f_temp = os.path.join(path, f) if os.path.isdir(f_temp): #如果是目录 find_dir(f_temp, result) os.chdir(os.pardir) #返回上一级目录 elif os.path.isfile(f_temp): #如果是文件 process_file_type(f_temp, result) return result#写csv文件def output_csv(out_file, contxt): with open(out_file, “a”, encoding=’utf-8′, newline=””) as wf: writer = csv.writer(wf) for i in contxt: writer.writerow(i)”’是否为文件/目录文件:D:\Database\mysql8\lib\libmysql.dll目录:D:\Database\mysql8其他:pass”’fpath = input(“请输入文件路径:”).strip()#添加cvs行首contxt = [[‘Upper Directory’, ‘FileName’, ‘FileType’]]if os.path.isfile(fpath): process_file_type(fpath, contxt) output_csv(“D:\\XXX\\isfile.csv”, contxt) print(“已为你生成csv文件,可打开查看详情!”)elif os.path.isdir(fpath): rs = find_dir(fpath, contxt) output_csv(“D:\\XXX\\isdir.csv”, rs) print(“已为你生成csv文件,可打开查看详情!”)else: pass输入的是文件路径:(例如 D:\Database\mysql8\lib\libmysql.dll)
输入的是目录路径:(例如 D:\Database\mysql8)
至此,遍历目录和文件,显示所有文件的名称和后缀,并修改指定文件名称等功能都实现了。这里,使用的是csv文件保存遍历查询的结果,需要导入csv模块。接下来,继续梳理不同文件类型的读写操作。
二、文件读写操作
在计算机的世界里,文件后缀的格式多不胜数,我们只需要知道常见的文件格式就行,比如:
.txt、.log、.json、.csv、.xls/.xlsx、.doc/.docx、.ppt、.xml、.yml等。
1、文件读写API
读写文件的方法为open(),有两种写法:
#默认,mode=’r’f=open(filename)#指定f=open(filename,mode[,encoding=’utf-8′,…])这里的模式mode参数有:
mode
含义
b
二进制模式。
打开一个文件进行更新(可读可写)。
t
文本模式 (默认)。
r
以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb
以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件,如图片等。
r
打开一个文件用于读写。文件指针将会放在文件的开头。
rb
以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件,如图片等。
w
wb
w
wb
a
打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a
打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab
以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
文件读取操作有关的方法有:
f.read():读取文件内容;
f.readline(size):读取一行,size表示读取该行多少个字符;
f.readlines():读取文件所有的行,以列表的形式返回;
f.tell():返回文件当前的位置;
f.seek(offset[, whence]):移动文件读取指针到指定位置,offset:开始的偏移量,whence:0 从文件开头开始算起,1 从当前位置开始算起,2 从文件末尾算起;
f.close():关闭文件,释放资源。
文件写入操作有关的方法有:
f.write(str):将字符串写入文件,返回的是写入的字符长度;
f.writelines(sequence):向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符;
f.flush():刷新文件内部缓冲,直接把内部缓冲区数据立刻写入文件, 而不是被动等待输出缓冲区写入。
注意:
普通的open()操作,无论读写,在最后都要使用close()方法手动关闭连接,这一点不要忽略了。而如果使用的是with open()语法形式,则不需要手动去关闭,举例说明:
#写入with open(“D:\\XXX\\test.txt”, ‘a ‘, encoding=’utf-8’) as wf: tell = wf.tell(); wf.write(“\n当前位置:杭州市西湖区留下街道梦溪街”)tell2=wf.tell();if tell2 > tell:print(“写入成功!”)if wf.closed == False: print(“——–测试———” ) wf.close()print(“文件是否关闭:” , wf.closed)#读取with open(‘D:\\XXX\\test.txt’,’r’,encoding=’utf-8′) as rf:context=rf.readlines()if rf.closed == False: print(“——-测试———-” ) rf.close()print(“文件是否关闭:”,rf.closed)print(“文件文本内容:” , context)
结果:
2、读写.txt/.log文件
使用上面的有关的API即可实现,比较简单。
3、读写.json文件
第一步:导入json模块;第二步:借助该模块dump()实现写入文件功能,load()实现读取文件功能;更多API可以参考:https://docs.python.org/zh-cn/3/library/json.html。import jsondicts = {‘a’:100, ‘b’:200, ‘c’:300}with open(‘D:\\XXX\\response.json’, ‘a’, encoding=’utf-8′) as wf:json_str=json.dump(dicts,wf)print(json_str)print(type(json_str))with open(‘D:\\XXX\\response.json’, ‘r’, encoding=’utf-8′) as rf:json_obj=json.load(rf)print(json_obj)print(type(json_obj))
结果:
4、读写csv文件/excel文件
csv文件已在上面的演示中用过了,不再举例。excel文件与csv文件看上去很相似,但依赖的模块和操作却不一样,excel文件的后缀是.xls 或 .xlsx,有许多模块支持 excel 的读写操作,比如:
openpyxl:A Python library to read/write Excel 2010 xlsx/xlsm files;
xlrd xlwt xlutils:三个模块搭配使用,对excel读写和复制等操作。
这里,使用 openpyxl 模块,使用pip命令下载:
pip install openpyxl
Demo:
写入结果:
读取日志:
注意:
读写excel时,单元格的坐标位置起始值是(1,1),load_workbook用于写excel、Workbook用于读取excel。更多API参考:https://openpyxl.readthedocs.io/en/stable/index.html#。
5、读写Word文件
Word文件的后缀有.doc 和 .docx 格式,以下模块支持word文档的读写:
python-docx:只支持.docx 格式,但可以将 .doc 转成 .docx 格式,从而间接支持 .doc 格式;(API参考:https://python-docx.readthedocs.io/en/latest/index.html)
win32com:调用系统的word功能,可以同时支持.doc 和 .docx 格式。
这里,使用 wun32com模块,使用pip命令下载:
pip install pywin32
我们能如此方便的调用Word,得益于其底层的COM(组件对象模型)可以被任意语言调用,操作word时需要知道以下对象:
Application:表示Word应用。包含了菜单栏、工具栏、命令以及所有文档等;
Documents:表示文档,可有多个。有打开Open()、创建Add()等API;
Selection:表示当前窗口的光标焦点或选择范围。有输入TypeText()、复制Copy()、粘贴Paste()、删除Delete()、全选WholeStory() 、左移MoveLeft()、右移MoveRight(start, end)等API;
Range:表示连续区域,用于区分文档不同位置,Range(0, 0)表示开始位置,Range()表示文末位置。
对 Selection 和 Range 也可以设置字体 Font、设置段落 ParagraphFormat 、设置 PageSetup、设置样式 Styles等。
Demo:(创建Word文档,并转储到txt文件中)
import win32comimport win32com.client#wordPath = ‘D:\\XXX\\SpringCloud学习笔记.docx’txtPath = ‘D:\\XXX\\转储创建的word文档1.txt’app = win32com.client.Dispatch(‘Word.Application’)#显示wordapp.Visible = True#创建word,并插入文字doc = app.Documents.Add()contxt1 = doc.Range(0, 0)contxt1.InsertBefore(‘Hello word\n’)contxt2 = doc.Range(10, 11)contxt2.InsertAfter(‘我是魏详详\n’)contxt3 = doc.Range()contxt3.InsertAfter(‘\n updatetime: 20210605’)#转储到其他文件:2为txt,doc.SaveAs(txtPath, 2)print(“文件转储成功!!!”)#关闭worddoc.Close()app.Quit()
转储txt内容:
Demo:(读取Word文档,并转储到txt文件中)
import win32comimport win32com.clientwordPath = ‘D:\\XXX\\SpringCloud学习笔记.docx’txtPath = ‘D:\\XXX\\SpringCloud学习笔记.txt’#打开officeapp = win32com.client.Dispatch(‘Word.Application’)#打开wordword = app.Documents.Open(wordPath)#打印word内容”’for i in word.Paragraphs: line = i.Range.Text print(line)”’#转储到其他文件:2为txt,word.SaveAs(txtPath, 2)print(“文件转储成功!!!”)#关闭wordword.Close()#关闭officeapp.Quit()
6、读写其他文件
文件类型那么多,不可能面面俱到的去演示读写操作的,从上面的Demo可以看到通用的思路如下:
要先明确是否需要导入模块,可以自行百度或去pip官网进行依赖查询;
尽量找到详细可参考的文档读写操作API,并亲测该方法的功能后再使用;
总结一下不知不觉中文件读写操作的东西梳理的还挺多的,这部分算是基础也很重要,后面学习爬虫,数据分析等都会使用得到。好了,人生苦短,学用Python,下一篇将梳理Python操作MySQL数据库,坚持就是胜利!!!