python之文件操作
文件操作:我们一般对文件操作有如下基本过程
1.打开文件,得到文件句柄并且赋值给一个变量
2.通过该文件句柄对文件进行一系列的操作
3.关闭文件
在这里解释下文件句柄:在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即文件句柄(file handle),该文件句柄对于打开的文件是唯一的识别依据。
在这里,举个栗子~
f = open(file='文本.txt',mode='r',encoding='utf-8') data = f.read() f.close()
这里对于文件各部分的解释如下:
file='文本.txt' 表示文件路径 mode='r' 表示只读(可以修改为其他) encoding='utf-8' 表示将硬盘上的 0101010 按照utf-8的规则去“断句”,再将“断句”后的每一段0101010转换成unicode的 01010101,unicode对照表中有01010101和字符的对应关系。 f.read() 表示读取所有内容,内容是已经转换完毕的字符串。 f.close() 表示关闭文件
此处的encoding必须和文件在保存时设置的编码一致,不然“断句”会不准确从而造成乱码。
P:就是怎么存进去就怎么读出来,编码保持一致
一般打开文件有这么几种类型:
1.r, 只读模式。(不允许写,只允许读)
2.w,只写模式。(不可读,不存在则创建:若存在,则删除再创建)
3.a,追加模式。(可读。不存在则创建,存在则只追加内容,在最后面)
其他类型,后续补充:
在以后使用较多的是:wb,rb主要是用来传输文件之类使用
还有写读和读写模式,但是实际应用种不是特别多
打开文件(一般有两种操作):
1.
f=open("yesterday","a",encoding="utf_8")
此方法需要手动关闭,或者等程序结束之后关闭,可添加f.closed()来关闭
2.
with open('yesterday','r',encoding="utf-8") as f:
用with方法打开文件,当with代码块执行完毕时,内部会自动关闭并释放文件资源。
此外,with方法还有支持同时管理上下文的功能
with open('log1') as obj1, open('log2') as obj2:
文件循环:
f = open("文本.txt",'r',encoding="utf-8") for line in f: print(line) f.close()
写文件
f = open(file='文本.txt',mode='w',encoding='utf-8') f.write('我是文本') f.close()
语法解释:
file=' 文本.txt' 表示文件路径 mode='w' 表示只写 encoding='utf-8' 将要写入的unicode字符串编码成utf-8格式 f.write(...) 表示写入内容,写入的内容是unicode字符串类型,内部会根据encoding转换为制定编码的 01101010101,即:字节类型 f.close()
追加
f = open("文本.txt",'a',encoding="gbk") f.write("\n杜姗姗 北京 167 49 13324523342") f.close()
注意:
文件操作时,以 “a”或“ab” 模式打开,则只能追加,即:在原来内容的尾部追加内容
写入到硬盘上时,必须是某种编码的0101010,打开时需要注意:
- ab,写入时需要直接传入以某种编码的0100101,即:字节类型
- a 和 encoding,写入时需要传入unicode字符串,内部会根据encoding制定的编码将unicode字符串转换为该编码的 010101010
文件的一些其他操作:
def fileno(self, *args, **kwargs): # real signature unknown 返回文件句柄在内核中的索引值,以后做IO多路复用时可以用到 def flush(self, *args, **kwargs): # real signature unknown 把文件从内存buffer里强制刷新到硬盘 def readable(self, *args, **kwargs): # real signature unknown 判断是否可读 def readline(self, *args, **kwargs): # real signature unknown 只读一行,遇到\r or \n为止 def seek(self, *args, **kwargs): # real signature unknown 把操作文件的光标移到指定位置 *注意seek的长度是按字节算的, 字符编码存每个字符所占的字节长度不一样。 如“路飞学城” 用gbk存是2个字节一个字,用utf-8就是3个字节,因此以gbk打开时,seek(4) 就把光标切换到了“飞”和“学”两个字中间。 但如果是utf8,seek(4)会导致,拿到了飞这个字的一部分字节,打印的话会报错,因为处理剩下的文本时发现用utf8处理不了了,因为编码对不上了。少了一个字节 def seekable(self, *args, **kwargs): # real signature unknown 判断文件是否可进行seek操作 def tell(self, *args, **kwargs): # real signature unknown 返回当前文件操作光标位置 def truncate(self, *args, **kwargs): # real signature unknown 按指定长度截断文件 *指定长度的话,就从文件开头开始截断指定长度,不指定长度的话,就从当前位置到文件尾部的内容全去掉。 def writable(self, *args, **kwargs): # real signature unknown 判断文件是否可写
占硬盘方式的文件修改代码示例
f_name = "兼职白领学生空姐模特护士联系方式utf8.txt" f_new_name = "%s.new" % f_name old_str = "乔亦菲" new_str = "[乔亦菲 Yifei Qiao]" f = open(f_name,'r',encoding="utf-8") f_new = open(f_new_name,'w',encoding="utf-8") for line in f: if old_str in line: new_line = line.replace(old_str,new_str) else: new_line = line f_new.write(new_line) f.close() f_new.close()
上面的代码,会生成一个修改后的新文件 ,原文件不动,若想覆盖原文件
import os f_name = "兼职白领学生空姐模特护士联系方式utf8.txt" f_new_name = "%s.new" % f_name old_str = "乔亦菲" new_str = "[乔亦菲 Yifei Qiao]" f = open(f_name,'r',encoding="utf-8") f_new = open(f_new_name,'w',encoding="utf-8") for line in f: if old_str in line: new_line = line.replace(old_str,new_str) else: new_line = line f_new.write(new_line) f.close() f_new.close() os.rename(f_new_name,f_name) #把新文件名字改成原文件 的名字,就把之前的覆盖掉了,windows使用os.replace # 帮助文档说明replace会覆盖原文件
其他的一些用法:
with open('yesterday','r',encoding="utf-8") as f: print(f.tell()) print(f.readline()) f.seek(0) print(f.tell())
seek(),用于移动文件读写指针到指定位置:tell()获取当前位置
在某一行插入一行文字:
count=0 for line in f: if count==9: print("--------我是分割线-------") count += 1 continue print(line.rstrip()) count+=1
其中的for循环就是遍历整个文件
文件的修改:
f=open('yesterday','r',encoding="utf-8") f_new=open('yesterday.bak','w',encoding="utf-8") for line in f: if "肆意的快乐等我享受" in line: line = line.replace("肆意的快乐等我享受","肆意的快乐等周栩强享受") f_new.write(line) f.close() f_new.close()
创建一个新文件,将修改后的内容写入新的文件,然后手动删除之前的文件,就能实现文件的修改。该方式下记得关闭文件
1,Alex Li,22,13651054608,IT,2013‐04‐01 2,Jack Wang,28,13451024608,HR,2015‐01‐07 3,Rain Wang,21,13451054608,IT,2017‐04‐01 4,Mack Qiao,44,15653354208,Sales,2016‐02‐01 5,Rachel Chen,23,13351024606,IT,2013‐03‐16 6,Eric Liu,19,18531054602,Marketing,2012‐12‐01 7,Chao Zhang,21,13235324334,Administration,2011‐08‐08 8,Kevin Chen,22,13151054603,Sales,2013‐04‐01 9,Shit Wen,20,13351024602,IT,2017‐07‐03 10,Shanshan Du,26,13698424612,Operation,2017‐07‐02
我们可以进行如下操作:
li = { #把文件里的每列添加到下面这些列表里 'id':[], 'name':[], 'age':[], 'phone':[], 'job':[], 'time':[] } f = open('员工信息表',"r",encoding="utf-8") for line in f: number,name,age,phone,job,time = line.strip().split(',') li['id'].append(number) li['name'].append(name) li['age'].append(age) li['phone'].append(phone) li['job'].append(job) li['time'].append(time)
就可以将文件的数据转换成列表的形式了