文件概述
若想将应用程序获取到的数据永久保存下来,就必须保存于硬盘中,操作系统把复杂的硬件操作封装成简单的接口给用户/应用程序使用,其中文件就是操作系统提供给应用程序来操作硬盘虚拟概念,用户或应用程序通过操作文件,可以将自己的数据永久保存下来。
-
文剑操作流程
- 打开一个文件,得到一个文件句柄并复制给变量
fp = open('a.txt',mode='r',encoding='utf-8')
- 通过文件句柄对文件进行操作
data = fp.read()
- 关闭文件
fp.colse()
-
关闭文件注意事项
打开一个文件包含两部分资源,操作系统级打开的文件+应用程序的变量,在程序操作完毕一个文件后,必须把文件的这两部分资源一个不落的回收掉,回收方法是:
fp.close()
但是我们经常操作完文件后,会忘记关闭文件,就会导致资源在使用,从而浪费导致程序运行慢等各种原因。
这里就可以使用上下文管理方式,去操作。
优势:只要写一次打开文件,当所属句柄下的代码执行完毕,程序结束时,会自动关闭文件,释放资源
with open('a.txt',mode='r',encoding='utf-8') as fp: pass
-
文件编码
上面我们看open打开文件的时候,括号里需要指定一些参数,先来讲这里的 encoding='utf-8' ,如果打开文件时,没有指定这个参数,默认会按系统默认的编码打开这个文件,大多数情况下我们默认的系统编码都是gbk,如果这个文件当初是以utf-8编码的,这样默认打开如果有中文很可能会得到不是你需要的结果,我们也称之为
乱码
.#若不想遇到乱码问题,文件是什么格式保存的,我们就需要用什么编码打开,推荐以后默认使用utf-8保存及编写 f=open('a.txt','r',encoding='utf-8')
-
文件的打开模式
文件句柄 = open('文件路径',模式)
模式 | 含义 |
---|---|
’r‘ | open for reading(default) |
'w' | open for writing,truncating the file first |
'a' | open for writing,appending to the end of the file is exists |
'b' | binary mode |
‘t' | 文字模式(默认) |
‘+' | 打开磁盘文件进行更新(读写) |
‘U' | universal newline mode (for backwards compatibility; should not be used in new code) |
- 打开文件的模式有(默认为文本模式):
r ,只读模式【默认模式,文件必须存在,不存在则抛出异常】 w,只写模式【不可读;不存在则创建;存在则清空内容】 a, 之追加写模式【不可读;不存在则创建;存在则只追加内容】
- 对于非文本文件,我们只能使用b模式,"b"表示以字节的方式操作(而所有文件也都是以字节的形式存储的,使用这种模式无需考虑文本文件的字符编码、图片文件的
jgp
格式、视频文件的avi
格式)rb wb ab 注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型,不能指定编码 "+" 表示可以同时读写某个文件 r+, 读写【可读,可写】 w+,写读【可读,可写】 a+, 写读【可读,可写】 x, 只写模式【不可读;不存在则创建,存在则报错】 x+ ,写读【可读,可写】 xb
- 由于历史的原因,换行符在不同的系统中有不同模式,比如在
unix
中是一个\n,而在windows中是‘\r\n’,用U模式打开文件,就是支持所有的换行模式,也就说‘\r’ '\n' '\r\n'都可表示换行t是windows平台特有的所谓text mode(文本模式),区别在于会自动识别windows平台的换行符。
Files opened in binary mode (appending 'b' to the mode argument) return contents as bytes objects without any decoding. b是以二进制的形式来读文件,但是显示出来的却不是0101,而是以字节的形式显示出来。 一个字节是8位二进制,所以计算机是自动帮你进行了转换。 请不要误会b模式是按照字节读。
-
文件的光标移动
read(3)
- 文件打开方式为文本时,代表读取3个字符
- 文件打开方式为bytes模式时,代表三个字节,(既是一个中文字符)
其余的文件内光标移动都是以字节为单位如seek,tell,truncate
注意:
- seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
- truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果
-
文件的修改
文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:
方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,
nodpad++
等编辑器)import os with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f: data=read_f.read() #全部读入内存,如果文件很大,会很卡 data=data.replace('alex','SB') #在内存中完成修改 write_f.write(data) #一次性写入新文件 os.remove('a.txt') os.rename('.a.txt.swap','a.txt')
方式二:讲硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件
import os with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f: for line in read_f: line=line.replace('alex','SB') write_f.write(line) os.remove('a.txt') os.rename('.a.txt.swap','a.txt')
-
练习
- 文件a.txt内容:每一行内容分别为商品名字,价钱,个数,求出本次购物花费的总钱数
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3
-
修改文件内容,把文件中的
alex
都替换成SB