文件处理的相关操作
文件处理
//先通过open()函数将硬盘中的文件加载到内存并返回一个文件对象
open()函数有多个参数,第一个参数是文件的路径,当然如果在同个文件目录下可以只写相对路径,否则就只可以写绝对路径,open()函数将文件加载内存时会有个默认解码,这个跟操作系统有关,open()函数会去操作系统获取默认的解码方式,在Windows系统下默认解码是"gbk",但要注意的是,文件是以什么编码的打开时就要以什么
解码不然就会乱码,默认打开文件的模式是只读
文件处理有两种方式,一种是文本方式,一种是二进制方式, 文本方式是打开文件时指定解码方式(utf-8或者gbk)读取进内存变成Unicode的模式,然后只要再内存里是Unicode的格式,就可以直接进行操作,比如输出再屏幕上, 我个人认为可能是print()这个函数会以默认的Unicode的格式解码内存的内容(其实再内存里也是二进制,只不过是Unicode的格式而已),然后输出在屏幕,如果修改的话因为在内存中嘛,文件读取进内存后也是变成Unicode格式的呀,你修改时直接以Unicode的格式对已经读取进内存的文件进行修改,在关闭文件时,操作系统自己会把内存里的Unicode格式的文件转换成文件原本在硬盘中的格式,然后文件就修改啦,因为文本格式写入的全部是字符串,所以如果写入是数字型不是字符串型的话就错
二进制方式-----读取进内存时不对文件的格式进行转换(不把它转换成内存的Unicode格式),而是以原生的二进制格式读取进内存(内存中也是二进制),这样的话如果要输出到显示屏就需要指定解码方式了(因为你没转换成Unicode格式,所以print()函数不能以默认的Unicode格式解码,所以要自己指定解码格式,就是文件原生的二进制是啥格式的),如果要修改的话,因为在内存中是以原生的二级制格式的嘛,如果直接修改的话就不行(因为会以默认的Unicode的格式进行修改,但很可惜文件读取进内存时没有转换成Unicode),所以修改时也需要指定字符串的格式 具体例子看下面
无论哪种格式,因为在
"r", 读操作:如果不存在文件则报错不会创建出来
事例
f = open("asd.txt") data = f.read() print(data) f.close() 结果 UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 8: illegal multibyte sequence //文件是以 “utf-8"存储的,打开是以默认方式"gbk"打开,自然就乱码咯 f = open("asd.txt",encoding="utf-8")//以”utf-8"解码 data = f.read() print(data) f.close() 结果 这是一段文字, 待输入的, 你懂吧
//read()方法,以文件结束符为结束读取,也就是读取文件的所以内容,可以有一个参数,表示读取多少给字符,默认是读取全部, 在文件操作中,只有read()方法的参数是表示字符数的,其余的所有文件操作中参数都是 表示字节数的
//readable()方法,判断该文件对象是否可读
f = open("asd.txt",encoding="utf-8") data = f.readable() print(data) f.close() 结果 True
//readline()方法,以换行符 \n 为读取结束符,也就是一次读取文件的一行, ps:换行符也输出,如果读完了还读也不报错,只是啥都不输出
f = open("asd.txt",encoding="utf-8") print("1",f.readline()) print("2",f.readline()) print("3",f.readline()) print("4",f.readline()) f.close() 结果 1 这是一段文字, 2 待输入的, 3 你懂吧 4
//readlines()方法,返回一个列表,将每一行的内容当成该列表的元素
f = open("asd.txt",encoding="utf-8") l = f.readlines() print(l) f.close() 结果 ['这是一段文字,\n', '待输入的,\n', '你懂吧']
"w" 写操作:
只可读不可写,当文件存在时会清空文件内容再进行写操作,当文件不存在时会创建这个新的文件
//writable()方法,判断文件对象是否可写
f = open("djh","w",encoding="utf-8") print(f.writable()) f.close() 结果 True
//write()方法,对文件进行写操作
f = open("djh","w",encoding="utf-8") f.write("my name is djh\n") f.write("many people think that i am very handsome\n") f.write("thank you\n") f.close() 结果 my name is djh many people think that i am very handsome thank you
//writelines()方法,以列表的形式传入写的内容
f = open("djh","w",encoding="utf-8") f.writelines(["my name is djh\n","many people think that i am very handsome\n","thank you\n"]) f.close() 结果 my name is djh many people think that i am very handsome thank you
“a" 追加模式:
追加模式本质上还是写模式,只不过是在文件的最后追加内容而不是把内容全部清空之后再进行操作,所以方法和 ”w” 模式一模一样
“+” 模式
"r+"---将文件打开可读可写 "w+"-----将文件里的数据全部清除打开可读可写 "a+"-------将文件打开光标指向文件末尾可读可写,都是可读可写的模式,但都是在自己的性质的基础上打开然后再可读可写,从光标开始 多数都是用“r+” 其他的基本无卵用
//另外一种打开文件的方式,不用手动关闭文件 ,操作系统会自己关闭
with open("djh","a+",encoding="utf-8") as fw:
// 二进制 “b”模式处理文件
读操作:
with open("djh","rb") as fr: data = fr.read() print(data) 结果 b'my name is djh\r\nmany people think that i am very handsome\r\nthank you\r\n\xe5\x85\x84\xe5\xbc\x9f\xe8\xb5\xb0\xe4\xb8\x80\xe6\xb3\xa2' 文件原本是: my name is djh many people think that i am very handsome thank you 兄弟走一波 with open("djh","rb") as fr: data = fr.read() print(data.decode("utf-8")) 结果 my name is djh many people think that i am very handsome thank you 兄弟走一波
写操作:
with open("djh1","wb") as fw: fw.write("djh好帅\n".encode("utf-8")) fw.write("thanks".encode("utf-8")) 结果 djh好帅 thanks
一些其他的文件操作,必须是文件操作才可以用下面的东西
//closed,后面是没有括号的,它不是函数
with open("djh1","wb") as fw: fw.write("djh好帅\n".encode("utf-8")) fw.write("thanks".encode("utf-8")) print(fw.closed) 结果 True
//encoding ,后面没有括号,输出是输出是该文件以什么编码打开
with open("djh1","w",encoding="utf-8") as fw: fw.write("djh好帅\n") fw.write("thanks") print(fw.encoding) 结果 utf-8
//flush()方法,将文件在内存里的数据刷进硬盘里,本来如果想要更新硬盘的数据想要close()才能刷新,但是flush()方法可以在文件没有关闭时直接更新,很多软件的自动保存都是这样搞的
//tell()方法,返回光标目前指定的字节数(从0开始计数)
with open("djh1","r+",encoding="utf-8") as fw: fw.readline()//会输出这一行的 \r\n 然后指向下一行的第一个 所以是17 print(fw.tell()) 结果 17
//newline,这个东西是让python输出最原始的换行符,因为在不同的平台,换行符的表示是不一样的 (在Windows中换行符是\r\n),所以python会自动给处理无论哪个平台换行符都是\n,而如果想要python不要自己擅自处理,就加上这个newline='' 就ok
with open("djh1","r+",encoding="utf-8") as fw: print(fw.readlines()) 结果 ['djh好帅\n', 'thanks\n', 'i love u'] with open("djh1","r+",encoding="utf-8",newline='') as fw: print(fw.readlines()) 结果 ['djh好帅\r\n', 'thanks\r\n', 'i love u']
//seek()方法,重新指定光标指定的字节数
with open("djh1","r+",encoding="utf-8",newline='') as fw: data = fw.read(3) print(data) print(fw.tell()) fw.seek(3) print(fw.read()) 结果 djh 9 jh好帅 thanks i love u
//truncate()方法,一个参数,表示截取前多个字节
with open("djh1","r+",encoding="utf-8",newline='') as fw: fw.truncate(18) 结果 djh好帅 t 源文件: djh好帅 thank you i love u
最后将一个用for循环迭代文件对象,先贴上代码
with open('人口普查','r',encoding='utf-8') as f: for each_line in f: print(each_line) 结果 {'name':'台湾','population':1356000000} {'name':'北京','population':1763000000} {'name':'上海','population':1006230000} {'name':'广州','population':9420000000} {'name':'佛山','population':1087200000}
os.rename('haproxy.conf','haproxy.conf_back')//将旧文件改名 os.rename('haproxy.conf_new','haproxy.conf')//将新文件改成旧文件的名字 os.remove('haproxy.conf_back')//删除旧文件