文件操作流程:
1.打开文件,得到文件句柄并赋值给一个变量;
2.通过句柄对文件进行操作;
3.关闭文件
################################33
1.打开文件方法:
a.只读方式打开文件
1 f = open("yesterday",encoding="utf-8") 2 data = f.read() 3 data2 = f.read() 4 print(data) 5 print(‘-----------data2------%s‘%data2) 6 7 执行结果: 8 就如夜晚的微风 9 May tease the candle flame 10 ... 11 When I was young 12 当我年少轻狂 13 -----------data2------
windows默认是gbk的编码格式,python默认是utf-8,如果不指定就使用操作系统的方式打开.文件指针,已经把data从开头读到最后,指针在最后了,所以第二个print只打印------data2----.
而且data属于文件内容,read()方法会打开全部内容,没法对文件进行操作。
正确的打开方式:
1 f=open("yesterday",‘r‘,encoding="utf-8") #以只读r方式utf-8的编码方式打开文件,不写默认是只读,但顺序必须在这 2 data=f.read() 3 print(data)
b."写"的方式打开文件
1 f=open("yesterday2",‘w‘,encoding="utf-8") 2 f.write("我爱北京天安门,\n") 3 f.write("天安门上太阳升") 4 f.close() 5 6 执行结果: 7 生成yesterday2,内容如下 8 我爱北京天安门 9 天安门上太阳升
c."追加"方式打开文件
1 f=open("yesterday2",‘a‘,encoding="utf-8") # a =append追加 2 f.write("我爱北京天安门,。。。。。。\n") 3 f.write("天安门上太阳升。。。。") 4 f.close() 5 6 执行结果: 7 天安门上太阳升我爱北京天安门,。。。。。。 8 天安门上太阳升。。。。
d.只读前几行
1 yesterday2----------------- 2 我爱北京天安门, 3 天安门上太阳升我爱北京天安门,。。。。。。 4 天安门上太阳升。。。。 5 ----------------------------------------------------------- 6 f = open("yesterday2",‘r‘,encoding="utf-8") 7 for i in range(3): 8 print(f.readlines()) 9 10 执行结果: 11 [‘我爱北京天安门,\n‘, ‘天安门上太阳升我爱北京天安门,。。。。。。\n‘, ‘天安门上太阳升。。。。‘] 12 [] 13 []
1 f = open("yesterday2",‘r‘,encoding="utf-8") 2 for line in f.readlines(): 3 print(line) 4 执行结果: 5 我爱北京天安门, 6 7 天安门上太阳升我爱北京天安门,。。。。。。 8 9 天安门上太阳升。。。。
1 f = open("yesterday2",‘r‘,encoding="utf-8") 2 for line in f.readlines(): 3 #print(line) 4 print(line.strip()) #strip()是把空格和换行符去掉 5 6 执行结果: 7 我爱北京天安门, 8 天安门上太阳升我爱北京天安门,。。。。。。 9 天安门上太阳升。。。。
e.举例:yesterday文件前9行插入“---我是分割线---”,文件正常打印
1 f = open("yesterday",‘r‘,encoding="utf-8") 2 for index,line in enumerate(f.readlines()): 3 if index == 9: 4 print(‘--------我是分隔线----------‘) 5 continue 6 print(line.strip()) 7 8 执行结果: 9 就如夜晚的微风 10 May tease the candle flame 11 ... 12 (第9行)--------我是分隔线---------- 13 ... 14 When I was young 15 当我年少轻狂
问题:
如果文件是20G大小,从硬盘读到内存中,内存就8G,程序就卡住了,内存就撑爆了,f.readlines读一行存在内存中一行,所以f.readlines只适合读小文件。上面是很low的写法.
解决方案:循环一行,删除一行,即内存中只保存一行
f.正确的循环打开方式
1 f = open("yesterday",‘r‘,encoding="utf-8") 2 for line in f: 3 print(line.strip()) 4 #这种方式,一行一行的读,并且内存中只保留一行,效率最高
举例:只修改第9行,即原第9行不打印了
1 f=open("yesterday",‘r‘,encoding=‘utf-8‘) 2 count=0 3 for line in f: 4 count += 1 5 if count==9: 6 print(‘---------我是分割线----‘) 7 count+=1 #count加1,否则下一条语句continue会把count一直是9,跳不出去 8 continue #直接跳到for第10行开始,循环执行即print打印第10行 9 print(line.strip())
2.文件句柄的增删改查
句柄tell、seek:
1 f = open("yesterday",‘r‘,encoding="utf-8") 2 print(f.tell()) 3 0 4 print(f.read(5)) #打印前5个字符,即前5位 5 就如夜晚的 6 print(f.tell()) #tell()方法以字符进行计位的 7 15
1 f = open("yesterday",‘r‘,encoding="utf-8") 2 print(f.tell()) #打印当前位置 3 0 4 print(f.readline()) 5 就如夜晚的微风 6 print(f.readline()) 7 May tease the candle flame 8 print(f.readline())# 一下读取三行 9 逗弄蜡烛的火苗 10 print(f.tell()) 11 74 12 f.seek(0) #文件指针又回到文件第一行 13 print(f.readline()) #查看到f又开始读取第一行 14 就如夜晚的微风 15 16 print(f.encoding) #打印文件的编码 17 utf-8 18 print(f.fileno()) #操作系统内部有个接口打开文件,在操作系统的编号,不用,不关注 19 3 20 print(f.flush()) #执行语句时,先写到内存的buffer缓存,达到缓存的大小才会写入硬盘,用途是存钱时存一次刷到硬盘一次 21 None
f.flush()方法:f.write()方法是写入内存的buffer,f.flush是把缓存中的内容写入到磁盘
1 >>> f = open("test.text","w") #在D盘下创建test.text文件 2 >>> f.write("hello1\n") #写入hello1字符串 3 7 4 >>> f.flush() #flush后才会有,即f.write是写入内存中的 5 >>> f.write("hello2\n") 6 7 7 >>> f.flush()
举例:打印进度条
1 import sys,time 2 for i in range(50): 3 sys.stdout.write("#") #sys的标准输出 4 sys.stdout.flush() 5 time.sleep(0.1) #秒 6 7 ##################################################
截断:指针从第10位到第20位的字符
1 f = open("yesterday",‘a‘,encoding=‘utf-8‘) 2 f.seek(10) #指针移动到第10位 3 f.truncate(20) #截取从第11位到第20位字符 4 5 执行结果: 6 我爱北京天安门,天安
读写r+:以只读和追加的方式打开
1 f=open("yesterday2",‘r+‘,encoding=‘utf-8‘) #读写:只读和追加的方式打开 2 print(f.readline()) 3 print(f.readline()) 4 print(f.readline())#指针到第三行 5 print(f.seek()) 6 f.write("----------diao------") #虽然指针在第3行,但还是在最后追加 7 print(f.readline()) 8 9 执行结果: 10 yesterday2最后一行添加----------diao------
写读w+:创建新文件,既可以写,又可以读。(结论:python2.7上这样就把源文件的字符修改掉变成新的,而python3不支持修改了。)
1 f=open("yesterday3",‘w+‘,encoding=‘utf-8‘) 2 f.write("-------------diao---------\n") 3 f.write("-------------diao---------\n") 4 f.write("-------------diao---------\n") 5 f.write("-------------diao---------\n") 6 print(f.tell()) 7 112 8 f.seek(10) 9 print(f.tell()) 10 10 11 print(f.readline()) 12 ---diao--------- 13 f.write("shouldbeatthebeginingofthesecondlien") 14 f.close() 15 16 执行结果: 17 生成yesterday3文件,文件内容 18 -------------diao--------- 19 -------------diao--------- 20 -------------diao--------- 21 -------------diao--------- 22 shouldbeatthebeginingofthesecondlien
总结:
写读模式没用,读写模式可以打开文件可以追加内容。
f=open("yesterday2",‘r+‘,encoding=‘utf-8‘) #文件句柄,读写模式
f=open("yesterday2",‘w+‘,encoding=‘utf-8‘) #文件句柄,写读模式
f=open("yesterday2",‘a+‘,encoding=‘utf-8‘) #文件句柄,追加读模式(追加模式下不能读,a+可以读了)
f=open("yesterday2",‘rb‘,encoding=‘utf-8‘) #文件句柄,二进制文件(二进制的方式去读)
f=open("yesterday2",‘rb‘,encoding="utf-8")
print(f.readline())
ValueError: binary mode doesn‘t take an encoding argument(二进制模式不能传递encoding编码了)
二进制读:
f=open("yesterday2",‘rb‘)
print(f.readline())
b‘-------------diao---------\r\n‘(b代表字节byte类型,windows上都是\r\n)
rb用途:
1.网络传输:socket传输(client--server传输文件,python3只能用二进制格式,python2还能用字符)
二进制写:
f=open("yesterday2",‘wb‘)
f.write("hello binary\n".encode()) #字符串转换成bytes
f.close()
Hello binary 文件内部以二进制存储
windows的换行是\r\n,linux是\n.
1 打开文件的模式有: 2 3 r,只读模式(默认)。 4 w,只写模式。【不可读;不存在则创建;存在则删除内容;】 5 a,追加模式。【可读; 不存在则创建;存在则只追加内容;】 6 "+" 表示可以同时读写某个文件 7 8 r+,可读写文件。【可读;可写;可追加】 9 w+,写读 10 a+,同a 11 "U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用) 12 13 rU 14 r+U 15 "b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注) 16 17 rb 18 wb 19 ab
文件修改:python3上不支持在源文件上修改,现在流行两种修改文件的方式:
1.vim打开文件,是把文件内容加载到内存中,修改完后再写回源文件;(缺点:2G的文件就没法玩了)
2.打开文件,修改文件后保存到另外一个文件中;(建议使用,方法为同时打开两个文件,边读边写,修改的话是打开文件替换后另存到新文件中)
举例说明:
1 f = open("yesterday2",‘r‘,encoding="utf-8") 2 f_new = open("yesterday4",‘w‘,encoding="utf-8") 3 for line in f: 4 if "文件yesterday2中的一行字" in line: 5 line = line.replace("文件yesterday2中的一行字","文件yesterday4中的一行字") 6 f_new.write(line) 7 f.close() 8 f_new.close() 9 10 执行结果: 11 创建新文件yesterday4,并写入 12 文件yesterday4中的一行字
with语句----------------------------------------
作用:
1.自动回收内存,自动关闭文件,释放文件资源;
2.与open区别是文件自动写入磁盘,而open方法是写入内存,必须flush后才能写入磁盘;
1 with open("yesterday2","r",encoding="utf-8") as f: 2 for line in f: 3 print(line) 4 #open后没有关闭文件,但with就会自动关闭了
在python2.7之后,with支持多文件的上下文管理,即
1 with open("yesterday2",‘r‘,encoding="utf-8") as f, 2 open("yesterday3",‘r‘,encoding="utf-8"): 3 for line in f: 4 print(line)