我们用python编写的程序放入到硬盘以永久保存,其中涉及到应用程序来操作硬件,而程序却无法直接操作硬件,需要操作系统作为中介,即操作系统将硬件操作封装成简单的接口供用户/应用程序使用。因此,文件操作通过操作系统供给应用程序来操作硬盘虚拟概念,用户或者应用程序可通过操作文件,将数据永久保存。
首先,简单介绍一个例子:
1 f = open('F:\pingguo.txt','r',encoding= 'utf-8') # 打开文件,将文件赋值给一个变量f 2 data = f.read() 读取文件里面的内容 3 print(data) 4 f.close() # 关闭文件
通过上面简单例子可以看出,变量f,其实也就是变量f_obj,f_handler,f_h,fh,即文件句柄open()函数是python的内置函数(其内部调用的是windows的系统命令),对文件的操作流程可以简述为:
1,打开文件,产生文件句柄
2,对文件句柄进行操作
3,关闭文件句柄
通过对列表,字典等增删改查一样,文件也有类似操作,但也有很大的不同,接下来分别对文件按读,写,追加等操作。首先是读操作:在python中,读操作为'r',即mode ='r'。但对于r模式,mode可以默认不写.
读操作通常由几种读方法,以下一一来介绍。
1. 文件内容全部读取 read()
1 1. 文件内容全部读取 read() 2 f = open('F:\诗歌.txt', encoding='utf_8', mode = 'r') 3 content = f.read() 4 print(content) 5 f.close()
显示结果为:
'''E:\python3.6.5\python.exe G:/PythonFile/week1/骑士计划/week_3/day_1/上课内容.py 杨柳青青江水平, 闻郎江上唱歌声。 东边日出西边雨, 道是无情却有情。 Process finished with exit code 0'''
2. read(n) 按照字符读取
1 f = open('F:\诗歌.txt',encoding= 'utf-8', mode = 'r') 2 content = f.read(10) 3 print(content) 4 f.close()
# 输出结果为: '''杨柳青青江水平, 闻
从输出结果可以看出,在读模式下,是按照字符读取数据,其中第一行最后一个空格也占用一个字符。
3 按行读取内容:readline()
1 f = open('F:\诗歌.txt',encoding= 'utf-8', mode='r') 2 print(f.readline().strip()) 3 print(f.readline().strip()) 4 print(f.readline().strip()) 5 print(f.readline().strip()) 6 print(f.readline().strip()) 7 f.close()
结果:
杨柳青青江水平,
闻郎江上唱歌声。
东边日出西边雨,
道是无情却有情。
每一次只读取一行代码,若没有strip()函数,则每读取一行都会空一行再读取下一行,当readline()多了,不会报错
4 按行读取,并返回一个list
1 4 按行读取,并返回一个list 2 f = open('F:\诗歌.txt',encoding='utf-8',mode='r') 3 content = f.readlines() # ['杨柳青青江水平,\n', '闻郎江上唱歌声。\n', '东边日出西边雨,\n', '道是无情却有情。'] 4 print(content) 5 f.close()
输出结果为一个列表,每一行内容代表一个元素,每一行最后都有一个换行符。
5 for 循环
1 f = open('F:\诗歌.txt',encoding='utf-8',mode='r') 2 for line in f: 3 print(line) 4 f.close()
'''杨柳青青江水平, 闻郎江上唱歌声。 东边日出西边雨, 道是无情却
可以看出,循环输出是每一行每一行执行,有空行,为了将空行删除使用line.strip()函数,如下:
1 f = open('F:\诗歌.txt',encoding='utf-8',mode='r') 2 for line in f: 3 print(line.strip()) 4 f.close()
一般在处理大量数据情况下,建议使用for循环,主要是在大量数据的文件下,用其他方法读是将文件所有数据都放入内存,将导致占用内存空间变大,消耗内存,而for循环则是将数据一行一行读入内存,每读完一行后就销毁,节省了内存的消耗。
rb 文件操作中凡是带b字母,都是与非文字类文件相关的
# 与文字类相关读取方式
1 f = open('F:\诗歌.txt',mode='rb') 2 content = f.readlines() 3 print(content) 4 f.close()
bytes方式进行读取,因此,不需要encode = 'utf-8'
# 输出结果以bytes方式进行输出:
''''[b'\xe6\x9d\xa8\xe6\x9f\xb3\xe9\x9d\x92\xe9\x9d\x92\xe6\xb1\x9f\xe6\xb0\xb4\xe5\xb9\xb3\xef'
b'\xbc\x8c\r\n', b'\xe9\x97\xbb\xe9\x83\x8e\xe6\xb1\x9f\xe4\xb8\x8a\xe5\x94\xb1\xe6\xad\x8c'
b'\xe5\xa3\xb0\xe3\x80\x82\r\n', b'\xe4\xb8\x9c\xe8\xbe\xb9\xe6\x97\xa5\xe5\x87\xba\xe8\
\xbf\xe8\xbe\xb9\xe9\x9b\xa8\xef\xbc\x8c\r\n', b'\xe9\x81\x93\xe6\x98\xaf\xe6\x97\xa0\xe6'
b'\x83\x85\xe5\x8d\xb4\xe6\x9c\x89\xe6\x83\x85\xe3\x80\x82']...
与非文字类读取文件相关:如读取图片
1 f = open('F:\不行.jpg',mode='rb') 2 content = f.read() 3 print(content) # b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00H\x00H\x00\x00\xf....... 4 f.close()
同理,只读取部分数据使用read(n)
1 f = open('F:不行.jpg',mode='rb') 2 content = f.read(9) # b'\xff\xd8\xff\xe0\x00\x10JFI' 模式下,按照字节读取 3 print(content) 4 f.close()
r+ 读写:先读后追加
1 f = open('F:\诗歌.txt',encoding='utf-8',mode='r+') 2 content = f.read(3) 3 print(content) 4 f.write('666') 5 f.close()
操作为先读取文件内3个字符后,光标移动到文件内容最后,再添加内容'666'
1 f = open('诗歌.txt',encoding='utf-8',mode='r+') 2 f.write('深圳你好!') 3 f.close()
'''深圳你好!水平, 闻郎江上唱歌声。 东边日出西边雨, 道是无情却有情。'''
从结果可知,不读而直接写会导致光标直接从开始覆盖。
1 # 报错 2 # f = open('诗歌.txt',mode='rb') 3 # # content = f.read(10) 4 # # print(content) 5 # f.write('666') 6 # f.close()
写操作
w :
# 若没有文件,则先创建文件后再写内容
# 若有文件,则先清空原文件内容,再写入新内容。
1 f = open('诗歌.txt',encoding='utf-8',mode='w') 2 f.write('深圳市南山区世外桃源。。。') 3 f.close()
wb:
1 f = open('F:\不行.jpg',mode='rb') 2 content = f.read() # 将图片信息保存到变量 3 print(content) # b'\xff\xd8\xff\xe0\x00\x10JFIF........ 4 f1 = open('不行1.jpg',mode='wb') 5 f1.write(content) 6 f.close() 7 f1.close()
非文字文件,先以bytes格式进行读出(rb),再用bytes格式进行写入(wb)
w+ 写读
1 f = open('诗歌.txt',encoding='utf-8',mode='w+') 2 f.write('深圳市南山区世外桃源。。。') # 先清空内容 3 f.seek(3) # 移动光标位置,是按字节移动,在utf-8模式下,每个文字移动三个字节,若为非3的倍数,则报错 4 content = f.read() 5 print(content) 6 f.close()
追加
a
没有文件时,将创建文件并将内容写进去
有文件时,直接在文件的最后面追加内容
1 f = open('t1.txt',encoding='utf-8',mode='a') 2 f.write('\n你是我的小丫小苹果。。。。') 3 f.close()
其他方法如: ab a+ a+b这里就不介绍了。
其他方法
readable writable seek
1 f = open('诗歌.txt',encoding='utf-8') 2 if f.readable(): 3 content = f.read() 4 print(content) 5 f.close()
可以打印出来,说明是可读的
1 f = open('诗歌.txt',encoding='utf-8') 2 if f.writable(): 3 content = f.read() 4 print(content) 5 f.close()
打印不出来,说明该文件是不可修改的
seek()
调整光标到开始:seek(0) 调整光标到结尾:seek(0,2)
1 f = open('诗歌.txt',encoding='utf-8') 2 f.seek(6) # 按照字节去移动光标 3 content = f.read() 4 print(content) 5 f.close()
将光标移动到六个字节位置,然后读取后面的内容。
1 f = open('诗歌.txt',mode='rb') 2 print(f.read()) 3 f.seek(6) # 按照字节去移动光标 4 content = f.read() 5 print(content) 6 f.close()
tell 告知光标的位置
1 f = open('诗歌.txt',encoding= 'utf-8') 2 f.seek(0,2) 3 print(f.tell()) # 统计一共有多少个字节 4 f.close()
truncate 要在writable模式下进行截取
r+ a+ ...不能在w模式下使用,对原文件进行截取
1 f = open('诗歌.txt',encoding='utf-8',mode='r+') 2 print(f.truncate(6)) 3 f.close()
1 主动关闭文件句柄
1 with open('诗歌.txt',encoding='utf-8',mode='r') as f1: 2 print(f1.read())
2 开启多个文件句柄
1 with open('诗歌.txt',encoding='utf-8') as f1,open('诗歌1.txt',encoding='utf-8',mode= 'w') as f2: 2 print(f1.read()) 3 f2.write('66666'
文件的改的操作
1,以读的模式打开原文件,产生一个文件句柄f1.
2,以写的模式创建一个新文件,产生一个文件句柄f2.
3,读取原文件内容,进行修改,并将修改后的写入新文件。
4,将原文件删除。
5,将新文件重命名成原文件。
low版本
1 import os 2 with open('诗歌.txt',encoding='utf-8') as f1,\ 3 open('诗歌2.txt',encoding='utf-8',mode= 'w') as f2: 4 old_content = f1.read() 5 new_content = old_content.replace('顾','colin') 6 f2.write(new_content) 7 os.remove('诗歌.txt') 8 os.rename('诗歌2.txt','诗歌.txt')
高级版本
1 import os 2 with open('诗歌.txt',encoding='utf-8') as f1,\ 3 open('诗歌2.txt',encoding='utf-8',mode= 'w') as f2: 4 for line in f1: 5 new_line = line.replace('顾','colin') 6 f2.write(new_line) 7 os.remove('诗歌.txt') 8 os.rename('诗歌2.txt','诗歌.txt')