一 文件操作基础流程
计算机系统分为:计算机硬件、操作系统、应用程序三部分
我们用python或者其他语言编写的应用程序若想要把数据永久保存下来,必须要保存到硬盘上去,这就涉及到应用程序要操作硬件。然而,应用程序是我发直接操作硬件的,这里就用到了操作系统。操作系统把复杂的操作硬件的操作过程封装成了简单的接口给用户、程序调用,其中文件就是操作系统提供给应用程序来操作硬盘的虚拟概念。用户或者应用程序通过操作文件,可以将自己的数据永久的保留下来。
有了文件的概念,我们无须再去考虑操作硬件的西街,只需要关注操作文件的流程
1.1 操作文件流程
#1. 打开文件,得到文件句柄并复制给一个变量 f1 = open('log1',mode='r',encoding='utf-8') #默认的打开方式是r,可忽略不写 #2. 通过文件句柄对文件进行操作 data = f1.read() #3 关闭文件句柄,收回占用内存 f1.close() print(data)
1.2关闭文件的注意事项:
# 打开一个文件包含两部分资源:操作系统级打开的文件+应用程序级的变量。在操作完一个文件时,必须把与该文件相关的这两部分全部回收。 # 回收方法: # f1.close() #回收操作系统级打开的文件 # def f1 #回收应用程序级的变量 # 启动 del f1 一定要在f1.close()之后。负责就会导致操作系统打开的文件还没有关闭,白白占用资源。 # 而python自动的垃圾回收机制决定了我们无需考虑 del f1。 这就要求我们,在操作完毕文件后后,一定要记住 f1.close() # 推荐不用手动关闭文件句柄的方式 with open('log1',mode='w',encoding='utf-8',) as f2: pass # 用with open的方式同时操作两个文件,将log1的内容写到log2中 with open('log1',mode='r',encoding='utf-8') as f1, open('log2',mode='w',encoding='utf-8') as f2: f2.write(f1.read())
1.3 文件编码
f = open(...) with open(...) as f 都是由操作系统打开文件,如果没有指定编码,那么打开文件的默认编码就是操作系统的默认编码,在windows下是gbk,在linux或者mac下是utf-8
若要保证不乱码,文件以什么编码方式存的就要以什么编码方式打开。
1.4 文件的打开模式
文件句柄 = open('文件路径','模式')
# 1.打开文件的模式有:(默认为文本模式) ''' r,只读模式 【默认模式,文件必须已经存在,不存在会报错】 w,只写模式 【不可读,不存在则创建,存在则清空】 a,只追加模式 【不可读,不存在则创建,存在则只追加内容而不清空】 ''' # 2.对于非文本内容,我们只能听使用b模式,'b'表示以字节的方式操作(所有文件都是以字节的方式存储的,使用这种模式无须考虑文本文件的字符编码、图片的jpg格式、视频的avi格式) ''' rb wb ab ###注: 以b模式打开文件时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码 ''' # 3.'+'模式(在原有模式基础上增加一个功能) ''' r+ 读写 w+ 写读 (写结束后,光标会移到最后,此时读取不到内容) a+ 写读 ''' # 4.以字节bytes类型操作的读写、写读、写读模式 ''' r+b 读写 w+b 写读 a+b 写读 '''
1.5 文件的操作方法
1.5.1常用操作方法
# read 全部读出 f1 = open('log1', encoding='utf-8') content = f1.read() # print(content) f1.close() #read(n) f1 = open('log1', encoding='utf-8') content = f1.read(5) # r 模式 按照字符读取。 print(content) f1.close() read(n) ##n = 1.2.3...... 1.文件打开方式为文本模式时,代表读取三个字符 2.文件打开方式为b模式时,带便读取三个字节 其余的文件光标移动都是以字节为单位,如: seek tell truncate 移动光标的方式 1. seek移动光标有三种方式0,1,2 。其中1,2必须在b模式下进行,但无论以哪种模式,都是以bytes为单位移动的 2.truncate 截断文件---暂不了解 f1 = open('log1', mode='rb') content = f1.read(3) # rb模式 按照字节读取。 print(content.decode('utf-8')) f1.close() #readline()按行读取 f1 = open('log1', encoding='utf-8') print(f1.readline()) print(f1.readline()) print(f1.readline()) print(f1.readline()) f1.close() #readlines() 将每一行作为列表的一个元素并返回这个列表 f1 = open('log1', encoding='utf-8') print(f1.readlines()) f1.close() ## 返回结果 ['log1 ', '第二行 ', '第三行 ', '第四行 ', '第五行 '] #for循环 f1 = open('log1',encoding='utf-8') for i in f1: print(i) f1.close()
#r+ 读写 f1 = open('log1', encoding='utf-8', mode='r+') print(f1.read()) f1.write(' 666') f1.close() f1 = open('log1', encoding='utf-8', mode='r+') f1.seek(0,2) f1.write('6666') #写done,光标在文件结尾。此时读不到内容 f1.seek(0)#调整光标到文件起始位 print(f1.read()) #光标 按照字节去运转 seek f1.close()
# # w模式 可写不可读 写是覆盖写 # f1 = open('log2', encoding='utf-8', mode='w') # f1.write('alex是披着高富帅外衣的纯屌丝.....') # f1.close() # f1 = open('log2', mode='wb') # f1.write('alex是披着高富帅外衣的纯屌丝.....'.encode('utf-8')) # f1.close() #w+ 写读模式 f1 = open('log2', encoding='utf-8', mode='w+') print('read1',f1.read()) #写读模式 先写后读,光标起始位置在文件结尾 f1.write('log22222') print('read2',f1.read()) f1.seek(0) print('read3',f1.read()) f1.close()
#a 追加写 f1 = open('log2', encoding='utf-8', mode='a') f1.write(' 老男孩') f1.close() #a+ f1 = open('log2', encoding='utf-8', mode='a+') f1.write('fdsafdsafdsagfdg') f1.seek(0) ##调整光标到起始位置 print(f1.read()) f1.close()
#其他操作方法: # read read(n) readline() readlines() write() close # readable writable # tell 告诉指针的位置 f1 = open('log2', encoding='utf-8', mode='w') f1.write('123456789') print(f1.tell()) # 光标位置 9 f1.seek(0) # 调整光标位置到起始位置 print(f1.tell()) # 光标位置 0 f1.seek(0,2) # 调整光标到结尾 print(f1.tell()) # 光标位置 9 f1.close() #seek(参数),seek(0,2) 调至最后 按照字节去调整光标 # with open() as: with open('log1', encoding='utf-8') as f1, open('log2', encoding='utf-8', mode='w')as f2: print(f1.read()) f2.write('777')
1.5.2 import os 系统修改文件的方式
文本软件修改一个文件的过程模拟:
文件的改
1,打开原文件,产生文件句柄。
2,创建新文件,产生文件句柄。
3,读取原文件,进行修改,写入新文件。
4,将原文件删除。
5,新文件重命名原文件。
## 将log1中的alex全体替换成SB import os with open('log1', encoding='utf-8') as f1, open('log1.bak', encoding='utf-8', mode='w') as f2: old_content = f1.read() new_content = old_content.replace('alex','SB') f2.write(new_content) os.remove('log1') os.rename('log1.bak','log1') # for循环实现 按行循环 import os with open('log1',encoding='utf-8',mode='r') as f1, open('log1.swap',encoding='utf-8',mode='w') as f2: for line in f1: newline = line.replace('SB','alex') f2.write(newline) os.remove('log1') os.rename('log1.swap','log1')
1.5.3 编码的补充
#编码的补充: s1 = b'xd6xd0xb9xfa' ## '中国'的gbk编码方式 s2 = s1.decode('gbk') print(s2) s3 = s2.encode('utf-8') print(s3) # b'xe4xb8xadxe5x9bxbd' print(s3.decode('utf-8')) # s1 = b'xd6xd0xb9xfa'.decode('gbk').encode('utf-8') # print(s1)