什么是文件
文件是操作系统提供给用户/应用程序操作硬盘的一种虚拟的概念/接口
为什么要有文件
所写的程序可以通过文件将数据永久保留到硬盘上
打开文件路径问题
# windows路径分隔符问题
# 路径:C:\nb\c\d.txt
# 解决方案一:推荐
# open(r'C:\nb\c\d.txt')
# 解决方案二:
# open('C:/nb/c/d.txt')
绝对路径和相对路径
相对路径
1、xxx.py想要打开a.txt,使用相对路径,有如下两种方式:
with open(r"b_file\a.txt",“r”) as file:
with open(r".\b_file\a.txtx", “r”) as file:
特别提示:… \是错误的,打开的是上级目录
2、ab.py尝试打开b_file下的a.txt,应该怎么写:
with open(r"…\b_file\aa.txt", “r”) as f:
绝对路径:
with open(r’C:\nb\c\d.txt’,“r”) as f:
操作文件:open() 方法
open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError。
注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。
#open()方法打开文件例子:
f=open(r'C:\nb\c\d.txt',mode='r') # f的值是一种变量/文件句柄,占用的是应用程序的内存空间
语法格式:
# 简洁语法:
open(file, mode='r', encoding=None)
# 完整语法:
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
参数说明:
file: 必需,文件路径(相对或者绝对路径)。
mode: 可选,文件打开模式
buffering: 设置缓冲
encoding: 编码格式,一般使用utf8
errors: 报错级别
newline: 区分换行符
closefd: 传入的file参数类型
encoding(编码参数):
如果没有指定encoding参数,会使用系统默认的编码格式,例如windows操作系统中,如果代码没有指定encoding参数,会默认使用windows的GBK编码格式
# 没有指定encoding参数操作系统会使用自己默认的编码
# linux系统默认utf-8
# windows系统默认gbk
with open('c.txt',mode='rt',encoding='utf-8') as f:
res=f.read() # t模式会将f.read()读出的结果解码成unicode
print(res,type(res))
# 报错UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 16: illegal multibyte sequence
mode详解
控制文件读写内容的格式:(t模式和b模式)
、t模式(默认的内容格式)只能打开文本文件
读写都是以str(Unicode)为单位的
文本文件
必须为open()指定encoding=‘utf-8’
2、b模式(bytes)
二进制方式,读写文件都是以bytes/二进制为单位的
可以针对所有文件(文本文件,图片,视频。。。)
不能指定encodingcabs
注意:b模式打开没有encoding编码这一说
总结:b模式和t模式对比
1、在操作纯文本文件方面t模式帮我们省去了解码环节,b模式则需要我们手动编码与解码,所以在操作纯文本文件方面t模式更加方便
2、针对非文本文件(图片、视频,音频。。)只能使用b模式
模式 | 描述 |
---|---|
+ | 打开一个文件进行更新(可读可写)。 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。如果原先有内容,执行写会把原先内容覆盖 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
+不能单独使用,必须配合r、w、a使用
t模式下读写实例:
user_db.txt内容如下
zhangsan:123:0
lisi:123:0
egon:123:0
alex:123:0
** r(默认的操作模式):只读模式,当文件不存在时报错,当文件存在时文件指针跳到开始位置**
with open('user_db.txt',mode='rt',encoding='utf-8') as f:
print('第一次读'.center(50,'*'))
res=f.read() # 把所有内容从硬盘读入内存
print(res)
with open('user_db.txt', mode='rt', encoding='utf-8') as f:
print('第二次读'.center(50,'*'))
res1=f.read()
print(res1)
//执行结果
***********************第一次读***********************
zhangsan:123:0
lisi:123:0
egon:123:0
alex:123:0
***********************第二次读***********************
w:只写模式,当文件不存在时会创建空文件,当文件存在会清空文件,指针位于开始位置
with open('user_db.txt',mode='wt',encoding='utf-8') as f:
# f.read() # 报错,不可读
f.write('你好世界\n')
# 执行后user_db.txt内容
'你好世界
强调
# 1、在以w模式打开文件没有关闭的情况下,连续写入,新的内容总是跟在旧的之后
# 2、如果以w模式打开一个原先有内容文件,则会清空文件内容
a:只追加写,在文件不存在时会创建空文档,在文件存在时文件指针会直接调到末尾
with open('e.txt',mode='at',encoding='utf-8') as f:
# f.read() # 报错,不能读
f.write('擦嘞1\n')
f.write('擦嘞2\n')
f.write('擦嘞3\n')
//执行结果
在e.txt文件末尾追加擦嘞
强调 w 模式与 a 模式的异同:
相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后
# 案例:a模式用来在原有的文件内存的基础之上写入新的内容,比如记录日志、注册
# 注册功能
name=input('your name>>: ')
pwd=input('your name>>: ')
with open('db.txt',mode='at',encoding='utf-8') as f:
f.write('{}:{}\n'.format(name,pwd))
b模式读写文件实例
b模式打开文件
fo.txt文件内容
zhangsan:123
lisi:123
egon:123
alex:123
代码
#b 模式打开文本文件(输出显示为bytes)
with open("fo.txt","rb") as f:
for line in f:
print(line)
//执行结果
b'zhangsan:123\r\n'
b'lisi:123\r\n'
b'egon:123\r\n'
b'alex:123'
#怎么将文件内容通过b模式打开显示正常呢?
#因为二进制打开时bytes类型,我们要将输出内容解码,并且按照当初文件存时候的编码
#去解码
#因为fo.txt文件存的时候时utf-8编码,所以我们用utf-8去解码
#手动解码显示为字符
with open("fo.txt","rb") as f:
for line in f:
print(line.decode("utf-8"),end="")
//执行结果
zhangsan:123
lisi:123
egon:123
alex:123
b模式写入内容到文本文件
解释:因为时b模式,所以只能写bytes数据到文件,因此,我们只能手动的将我们要写到文件的内容进行编码再写入,t模式时自动帮我们转了(encoding指定的)
写入前fo.txt文件内容
zhangsan:123
lisi:123
egon:123
alex:123
代码
with open("fo.txt","ab") as f:
f.write("\n王二:123".encode("utf-8"))
执行后fo.txt文件内容
zhangsan:123
lisi:123
egon:123
alex:123
王二:123
一个特殊的文件操作模式x模式(了解知识)
x模式
x,只写模式[不可读;不存在则创建,存在则报错]
# 实例
#a.txt文件存在(执行时提示报错)
#with open('a.txt',mode='x',encoding='utf-8') as f:
# pass
# c.txt文件不存在(创建c.txt文件)
# with open('c.txt',mode='x',encoding='utf-8') as f:
# f.read()
#打开文件时,文件指针在开头
with open('d.txt',mode='x',encoding='utf-8') as f:
f.write('哈哈哈\n')
with语句
使用with…as 关键字
上下文管理的语句块并不会开启新的作用域
with语句块执行完的时候,会自动关闭文件对象
为了避免打开文件后忘记关闭,可以通过管理上下文,即:
with open('log','r') as f:
...
如此方式,当with代码块执行完毕时,内部会自动关闭并释放文件资源。打开多个文件:
with open('yesterday','r',encoding='utf-8') as f,\
open('yesterday2','r',encoding='utf-8') as f2: ...
# 例子:打开单个文件yesterday2文件内容:
1:www.runoob.com
2:www.runoob.com
3:www.runoob.com
4:www.runoob.com
7:www.runoob.com
# 代码
with open('yesterday2','r',encoding='utf-8') as f:
for line in f:
print(line.strip())
# 执行结果
1:www.runoob.com
2:www.runoob.com
3:www.runoob.com
4:www.runoob.com
7:www.runoob.com
# 注解:
with open('yesterday2','r',encoding='utf-8') as f:
# 等同于
f=open('yesterday2','r',encoding='utf-8')
f.close()
# 例子:打开多个文件
yesterday文件内容:
f1:www.runoob.com
f1:www.runoob.com
f1:www.runoob.com
f1:www.runoob.com
f1:www.runoob.com
yesterday2文件内容:
f2:www.runoob.com
f2:www.runoob.com
f2:www.runoob.com
f2:www.runoob.com
f2:www.runoob.com
# 代码
with open('yesterday','r',encoding='utf-8') as f,\
open('yesterday2','r',encoding='utf-8') as f2:
for line in f:
print(line.strip())
for line2 in f2:
print(line2.strip())
# 执行结果
f1:www.runoob.com
f1:www.runoob.com
f1:www.runoob.com
f1:www.runoob.com
f1:www.runoob.com
f2:www.runoob.com
f2:www.runoob.com
f2:www.runoob.com
f2:www.runoob.com
f2:www.runoob.com