Python文件操作
编码相关
字符串类型(str),在程序中用于表示文字信息,本质上是unicode编码中的二进制。
name = "中文"
-
name = "中文" data = name.encode('utf-8') print(data) # b'\xe4\xb8\xad\xe6\x96\x87' result = data.decode('utf-8') print(result) # "中文" -
文件操作语法:
# 打开文件
fp = open(文件,模式,编码集)
# 默认打开模式就为r
fp = open('a.txt','r',encoding='utf-8')
# 读取文件内容
fp.read()
# 写入文件的内容
fp.write()
以文本模式读文本文件
file_object = open('info.txt', mode='rb')
data = file_object.read()
print(data)
text = data.decode("utf-8")
print(text)
# mode='rt',以文本模式读取,不用再使用decode转化
file_object = open('info.txt', mode='rt', encoding='utf-8')
data = file_object.read()
print(data)
file_object.close()
读图片等非文本内容文件
# 当: mode='rb' ,不要加:encoding='utf-8'
file_object = open('a1.png', mode='rb')
data = file_object.read()
file_object.close()
print(data)
读文件时,文件不存在程序会报错:
Traceback (most recent call last):
File "test.py", line 2, in <module>
file_object = open('test.txt', mode='rt', encoding='utf-8')
FileNotFoundError: [Errno 2] No such file or directory: 'test.txt'
import os
file_path = "info.txt"
exists = os.path.exists(file_path)
if exists:
file_object = open('infower.txt', mode='rt', encoding='utf-8')
data = file_object.read()
file_object.close()
print(data)
else:
print("文件不存在")
windows路径分隔符问题
open('C:\a\nb\c\d.txt')
解决方案一:推荐
open(r'C:\a\nb\c\d.txt')
解决方案二:
open('C:/a/nb/c/d.txt')
文件的写入操作
b:要求写入的内容需要是字节类型。
写文本文件
file_object = open("t1.txt", mode='wt', encoding='utf-8')
file_object.write("写入")
file_object.close()
写图片等文件
f1 = open('a1.png',mode='rb')
content = f1.read()
f1.close()
f2 = open('a2.png',mode='wb')
f2.write(content)
f2.close()
写文件案例1:去网上下载一点文本,文本信息写入文件。
import requests
res = requests.get(
url="https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=20",
headers={
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
}
)
# 网络传输的原始二进制信息(bytes)
# res.content
file_object = open('files/log1.txt', mode='wb')
file_object.write(res.content)
file_object.close()
写文件案例2:去网上下载一张图片,图片写入本地文件。
import requests
res = requests.get(
url="https://hbimg.huabanimg.com/c7e1461e4b15735fbe625c4dc85bd19904d96daf6de9fb-tosv1r_fw1200",
headers={
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
}
)
# 网络传输的原始二进制信息(bytes)
# res.content
file_object = open('files/美女.png', mode='wb')
file_object.write(res.content)
file_object.close()
========= ===============================================================
Character Meaning
--------- ---------------------------------------------------------------
'r' open for reading (default)
'w' open for writing, truncating the file first
'x' create a new file and open it for writing
'a' open for writing, appending to the end of the file if it exists
'b' binary mode
't' text mode (default)
'+' open a disk file for updating (reading and writing)
The default mode is 'rt' (open for reading text).
关于文件的打开模式常见应用有:
-
只读:
r、rt、rb(常用)-
存在,读
-
不存在,报错
-
-
只写:
w、wt、wb(常用)-
存在,清空再写
-
不存在,创建再写
-
-
只写:
x、xt、xb(基本不用)-
存在,报错
-
不存在,创建再写。
-
-
只写:
a、at、ab【尾部追加】(常用)-
存在,尾部追加。
-
不存在,创建再写。
-
-
读写
-
r+、rt+、rb+,默认光标位置:起始位置
-
文件存储二进制字节流
二进制字节流: 用于传输数据或者存储数据的一种数据格式
b"abc" b开头的字节流要求数据只能是ascii编码中的字符,不能是中文
data = b"中文"
print(data,type(data))
报错如下:
SyntaxError: bytes can only contain ASCII literal characters.
将字符串和字节流(Bytes流)类型进行转换 (参数写成转化的字符编码格式)
encode() 编码 将字符串转化为字节流(Bytes流)
decode() 解码 将Bytes流转化为字符串
data = b"abc"
data = "中文".encode("utf-8")
print(data,type(data))
res = data.decode("utf-8")
print(res,type(res))
结果输出:
b'\xe4\xb8\xad\xe6\x96\x87' <class 'bytes'>
中文 <class 'str'>
utf-8下,一个中文占用3个字节
utf-8编码格式下:默认一个中文三个字节,一个英文或符号占用一个字节。
data = "中文".encode("utf-8")
# 计算字节总大小
print(len(data))
结果输出:
6
把中字这个字节流进行反解恢复成原来中的字符 "中"
res = b"\xe4\xb8\xad".decode()
print(res)
结果输出:
中
文件存储二进制的字节流
如果存储的是二进制字节流,指定模式wb,不要指定encoding编码集,否则报错
fp = open("ceshi2.txt",mode="wb")
strvar = "红鲤鱼绿鲤鱼与驴".encode("utf-8")
fp.write(strvar)
fp.close()
文件读取二进制的字节流
fp = open("ceshi2.txt",mode="rb")
res = fp.read()
fp.close()
print(res)
print(res.decode())
输出结果:
b'\xe7\xba\xa2\xe9\xb2\xa4\xe9\xb1\xbc\xe7\xbb\xbf\xe9\xb2\xa4\xe9\xb1\xbc\xe4\xb8\x8e\xe9\xa9\xb4'
红鲤鱼绿鲤鱼与驴
复制文件
所有的图片,音频,视频都需要通过二进制字节流来进行存储传输.
先把原文件的二进制字节流读取出(事先准备好一个图片文件:集合.png)
fp = open(r"D:\python\集合.png",mode="rb")
res = fp.read()
fp.close()
# 计算文件中的字节个数,计算出来的值就是文件的大小。
print(len(res))
再把二进制字节流写入到另外一个文件中,相当于复制
fp = open("集合2.png",mode="wb")
fp.write(res)
fp.close()
read()
功能:读取字符的个数(里面的参数代表字符个数)
注意:从当前光标往右边读
read,读
读所有【常用】
f = open('info.txt', mode='r',encoding='utf-8')
data = f.read()
f.close()
f = open('info.txt', mode='rb')
data = f.read()
f.close()
读n个字符(字节)【会用到】
f = open('info.txt', mode='r', encoding='utf-8')
# 读1个字符
data = f.read(1)
f.close()
print(data)
f = open('info.txt', mode='r',encoding='utf-8')
# 读1个字符
chunk1 = f.read(1)
chunk2 = f.read(2)
print(chunk1,chunk2)
f.close()
f = open('info.txt', mode='rb')
# 读1个字节
data = f.read(3)
f.close()
print(data, type(data))
f = open('info.txt', mode='rb')
# 读1个字节
chunk1 = f.read(3)
chunk2 = f.read(3)
chunk3 = f.read(1)
print(chunk1,chunk2,chunk3)
f.close()
seek()
功能:调整指针的位置(里面的参数代表字节个数)
seek(0) 把光标移动到文件的开头(0 字节就是文件开头)
seek(0,2) 把光标移动到文件的末尾
tell()
功能:当前光标左侧所有的字节数(返回字节数)
打开模式
w write 写入模式
文件不存在则创建文件,存在的话则打开清空内容,并且将文件指针放在文件的开头
r read 读取模式
文件不存在则报错! 存在的话则打开文件,并且将文件指针放在文件的开头
a append 追加模式
文件不存在则创建文件,存在的话则打开文件,并且将文件指针放在文件的末尾
x xor 异或模式(不常用)
文件已存在则报错! 不存在的话则创建文件,将文件指针放在文件的开头
扩展模式
配合打开模式的辅助模式,自己单独不能使用
+ plus 增强模式(可以让文件具有读写功能)
b bytes bytes模式(二进制字节流)
模式一共16种
w,w+,wb,wb+
r,r+,rb,rb+
a,a+,ab,ab+
x,x+,xb,xb+
r+ 先读后写
fp = open("ceshi3.txt",mode="r+",encoding="utf-8")
# 先读
res = fp.read()
# 在写
fp.write("ab")
# 在读
fp.seek(0) # 通过seek把光标移动到开头
print(fp.read())
fp.close()
r+ 先写后读
fp = open("ceshi3.txt",mode="r+",encoding="utf-8")
# 移动光标到最后,否则r模式下,原字符会被覆盖
fp.seek(0,2)
# 先写
fp.write("cd")
# 把光标移动到文件的开头
fp.seek(0)
# 在读
res = fp.read()
print(res)
fp.close()
w+ 可读可写,清空重写(默认可以创建新的文件)
fp = open("ceshi4.txt",mode="w+",encoding="utf-8")
fp.write("abc")
fp.seek(0)
print(fp.read())
fp.close()
a+ 可读可写,追加写入 (默认可以创建新的文件)
fp = open("ceshi5.txt",mode="a+",encoding="utf-8")
fp.write("def")
# 读内容
fp.seek(0)
print(fp.read())
fp.close()
r+和a+区别
r+模式基于当前光标所在位置进行写入覆盖
a+模式会强制把光标放到文件末尾进行追加写入
# fp = open("ceshi5.txt",mode="r+",encoding="utf-8")
fp = open("ceshi5.txt",mode="a+",encoding="utf-8")
fp.seek(3) # 从头数 3个字节的位置
# fp.write("zxc") # 模式会强制把光标放到文件末尾进行追加写入
print(fp.read())
fp.close()
seek、tell、read的使用
fp = open("ceshi5.txt",mode="r+",encoding="utf-8")
fp.seek(4)
# tell 当前光标左边所有内容的字节数
res = fp.tell()
print(res)
在r+模式下 read(2) 代表读取2个字符 在rb模式下 read(2) 代表读取2个字节
fp.read(2) # 当前光标往右所有的字符内容
print(fp.tell())
fp.close()
注意点:seek在移动时,又可能移动到某个汉字的字节中间,导致原字节无法解析
fp = open("ceshi6.txt",mode="r+",encoding="utf-8")
fp.seek(3)
print(fp.read())
fp.close()
with语法
自动实现文件关闭操作
方法一.读取二进制字节流
with open("集合2.png",mode="rb") as fp:
res = fp.read()
with open("集合3.png",mode="wb") as fp:
fp.write(res)
方法二.继续简化
with open("集合3.png",mode="rb") as fp1 , open("集合4.png",mode="wb") as fp2 :
res = fp1.read()
fp2.write(res)
手动刷新缓冲区
直接把内容写入到文件
fp.flush()
文件相关的函数
readable()
功能: 判断文件对象是否可读
writable()
功能: 判断文件对象是否可写
fp这个对象本身是迭代器,可以把文件中的内容按照换行一行一行遍历出来
fp = open("ceshi1.txt",mode="r",encoding="utf-8")
for i in fp:
print(i)
readline()
功能: 读取一行文件内容
如果想读取所有的行(假设有4行),就得写4次 fp.readline()
with open("ceshi1.txt",mode="r",encoding="utf-8") as fp:
res = fp.readline()
print(res)
res = fp.readline()
print(res)
res = fp.readline()
print(res)
res = fp.readline()
print(res)
一次把所有内容都读取出来
with open("ceshi1.txt",mode="r",encoding="utf-8") as fp:
# 先读取一行
res = fp.readline()
# 判断是不是空,不是空再循环
while res:
print(res)
# 再读取一行,放到循环中判断.
res = fp.readline()
注意点:
readline(n)
n是读取的字符数
with open("ceshi1.txt",mode="r",encoding="utf-8") as fp:
"""
读取的字符数量 > 实际当前行字符数量的时候 => 按照当前行读取
读取的字符数量 < 实际当前行字符数量的时候 => 按照实际数量来读
"""
res = fp.readline(300)
print(res)
readlines()
功能:将文件中的内容按照换行读取到列表当中
lst_new = []
with open("ceshi1.txt",mode="r+",encoding="utf-8") as fp:
lst = fp.readlines()
for i in lst:
lst_new.append(i.strip())
print(lst_new)
writelines()
功能:将内容是字符串的可迭代性数据写入文件中
参数:内容为字符串类型的可迭代数据
lst = ['床前明月光', '疑是地上霜', '举头望明月', '低头想家乡']
with open("ceshi2.txt",mode="w+",encoding="utf-8") as fp:
for i in lst:
fp.writelines(i+"\n")
truncate()
功能: 把要截取的字符串提取出来,然后清空内容将提取的字符串重新写入文件中 (字节)
with open("ceshi2.txt",mode="r+",encoding="utf-8") as fp:
fp.truncate(3)
浙公网安备 33010602011771号