Python文件操作

编码相关

字符串类型(str),在程序中用于表示文字信息,本质上是unicode编码中的二进制。

name = "中文"

字节类型(bytes)

  • 可表示文字信息,本质上是utf-8/gbk等编码的二进制(对unicode进行压缩,方便文件存储和网络传输。)

    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).

关于文件的打开模式常见应用有:

  • 只读:rrtrb (常用)

    • 存在,读

    • 不存在,报错

  • 只写:wwtwb(常用)

    • 存在,清空再写

    • 不存在,创建再写

  • 只写:xxtxb  (基本不用)

    • 存在,报错

    • 不存在,创建再写。

  • 只写:aatab【尾部追加】(常用)

    • 存在,尾部追加。

    • 不存在,创建再写。

  • 读写

    • 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)


 

 

posted @ 2022-11-09 19:52  屠魔的少年  阅读(9)  评论(0)    收藏  举报