Python基础(3)文件处理,掌握如何对文件进行操作,针细!

前言:

使用Python提供的open方法可以对文件进行读写操作

Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数。



open的介绍

open(file_path,mode,enconding)	# 前两个参数必备

# 第一个参数 文件的路径地址,默认是相对路径查找,也可以使用绝对路径
# 第二个参数 文件的打开方式
# 第三个参数 打开文件的编码

# mode 三种模式:
# t(文本模式 默认)b(二进制模式)x(写模式,新建文件,如果已存在文件会报错)

mode 参数:

模式描述
t文本模式 (默认)
x写模式,新建一个文件,如果该文件已存在则会报错
b二进制模式
x打开一个文件进行更新(可读可写)
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式
r+打开一个文件用于读写。文件指针将会放在文件的开头
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等
w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件
w+打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件
wb以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等
wb+以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等
a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写
ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写

open的使用


+号给模式增加读写,目前测试只适用于r模式,但是不建议使用,因为每种模式都对某一方面占优势,一般情况下,读内容使用r即可,写内容使用w或者a即可

读文件内容

r 模式,用于读文件内容

# 将mode模式改为r,表示以读的形式打开这个文件
f = open('a.txt','r',encoding='utf-8')	# 这里通过utf-8解码
'''

重点:在硬盘读取内容时,要进行解码,解码指定标准必须和文件存入硬盘时编码是一致的
否则会造成乱码。

可以尝试将写入文件时编码改成gbk,写入时放入一点中文,然后读取文件解码用utf-8,
这么做的结果就是 无法通过utf-8对gbk文件进行解码,最终报错

'''
body = f.read()	# 读取文件内容
print(body)
f.close()	# 关闭文件

读图片内容

rb 读二进制内容的文件如:图片、视频等

# 注意:这里不需要使用编码,因为我们本来就是拿二进制,进行编码会报错
f = open('white.jpg','rb') # 这里图片与我当前文件在同一文件夹内
print(f.read())
f.close()

在这里插入图片描述

写入文件内容

w 写模式,如果已存在文件那么会清空文件原有内容从头开始编辑,如果没有则创建

# 使用open对文件操作,默认就是以文本模式,这里w可以看成wt,t表示只能对文本操作
f = open('a.txt','w',enconding='utf-8')
'''
这里encoding代表,指定字符编码格式将文件内容写入硬盘
因为计算机只能识别二进制数,那么就需要对我们书写的字符进行编码
经过编码后,最终写入硬盘的都是二进制,
python3 默认就是utf-8编码格式

utf-8 作为最常用编码,但仍有部分文件内容是用于其他编码写入,所以经常达不到统一
所以有时在其他读文件时产生乱码现象

使用open以后,会返回一个文件对象

'''
f.write('123')	# 对这个文件写入一点内容
f.close()	
# 注意:使用完文件对象以后,通知操作系统关闭文件,避免占用系统资源。

执行完毕以后,会发现当前文件夹下多了一个a文件

在这里插入图片描述

再次使用w模式

f = open('a.txt','w',encoding='utf-8')
f.write('World')
f.close()

查看效果:原内容已经被清空,写入了新的内容

在这里插入图片描述


完整复制出一张图片

使用wb,表示往文件内写入二进制

f = open('white.jpg','rb')
source_img = f.read()	# 先获取原图片的二进制内容

f2 = open('new_white.jpg','wb')
f2.write(source_img)	# 原图片的二进制,写入新文件

f.close()
f2.close()	# 记得关闭文件,避免占用系统资源

查看效果

在这里插入图片描述

优化操作

因为程序是先将文件内容读入内存,最后最写入一个新的文件,如果原文件容量较大,那么读入到内存里面会对内存造成很大的压力,所以建议使用下面这种方式:

f = open('white.jpg','rb')  # 源文件

f2 = open('new_white.jpg','wb') # 创建一个新的图片文件
for i in f:    # 每次读源文件一部分内容,写入新的文件,有效减少了对内存的压力
    f2.write(i)
f.close()
f2.close()	# 记得关闭文件,避免占用系统资源

# 相对大文件拷贝的一种优化方案,小文件可以使用上面那种

对文件进行追加内容

a 模式,将光标移到末行追加内容,如果文件不存在则创建文件

在这里插入图片描述

代码实现

f = open('a.txt','a',encoding='utf-8')
f.write('哈哈')   # 往文件末尾追加内容
f.close()

'''
	可以增加换行
	f = open('a.txt','a',encoding='utf-8')
	f.write('哈哈\n')   # 表示输入完哈哈以后换行一次
	f.close()
'''

实现后

在这里插入图片描述
ab 模式用于对文件追加二进制内容(不常用)

w模式与a模式不同的是在打开文件时的效果:

使用w模式:在打开文件时就会清空原有内容,再从头开始编辑。
使用a模式:只会用于追加内容。
如果是一个空文件,则两个模式效果相同


给予每种模式对文件的读写能力

使用+ 给模式提供未拥有的属性,如:

给r模式提供可以写的操作
给w模式提供可以读的操作
给a模式提供可以读的操作

给予r模式+号的话,可以拥有对文件的写能力

其中w模式是写入内容的,从头开始写内容,写完后光标默认是停留在最后一行的,如果给它+号赋予读的能力,那么也是读不了内容的,因为读内容是从光标当前位置开始向后读
a模式更不用说,默认光标就在最后一行,虽然说有读的能力,但是无法使用出来。

实例:

# 给r 模式增加写的能力
f = open('a.txt','r+',encoding='utf-8')
print(f.readable())	# 查看对文件是否有写能力	True 表示具备写的能力	

f.write('1234')	# 可以写入内容


# 给w 模式增加读的能力
f = open('a.txt','w+',encoding='utf-8')
print(f.readable())	# 查看对文件是否具备读能力
f.write('123')	# 因为是w模式需要,需要写点内容

print(f.read())	# 发现读不出内容,因为是光标写入时走到末尾的原因


# 给a 模式增加读的能力
f = open('a.txt','a+',encoding='utf-8')
print(f.readable())	# 查看对文件是否具备读能力

f.write('123')	# 写点内容

print(f.read())	# 发现读不出内容,默认光标直接跳到结尾


操作文件的常用方法


学习一下操作文件对象的几种常用方法,可以自如的操作文件


光标的移动

控制光标的移动,可以让光标停留任何位置

f = open('a.txt','r',encoding='utf-8')
print(f.read())	# 读取文件内容
print(f.read())
# 发现已经无法读取文件内容,是读文件是从头到尾读,读过一次 所以光标已经在最后一个了

'''
控制光标使用方法

f.seek(移动的字符个数,模式)
三种模式:
0:参照开头位置移动指针
1:参照当前光标位置移动指针
2:参照末尾位置移动指针

只有0模式可以在 t(文本模式)使用,1、2只能在b(二进制模式)下使用

print(f.tail())	# 查看光标当前的位置

'''

f = open('a.txt','r',encoding='utf-8')
print(f.read())	# 读取文件内容
f.seek(0,0)		# 将光标移动到开头
print(f.read()) 


在这里插入图片描述

读取文件的常用方法

可以根据需求读取文件所需内容

t模式 read(找到的字符个数)
b模式 read(找到的字节个数) 1个中文3个字节 (基本不用这种形式读二进制文件)

f = open('a.txt','r',encoding='utf-8')
res = f.read(1)	# 读取字符的个数,1代表光标只移动一下 读取第一个字符
# res = f.read(3)	# 如果是rb模式,存在一个中文就要用3个字节来读
print(res)


按行读内容
f = open('a.txt','r',encoding='utf-8')
print(f.readline(),end='')	# 第一次读取一行内容,光标停留在第一行末尾
123
print(f.readline(),end='')	# 第二次读取二行内容,从第一行末尾读到第二行末尾
456

把文件内容按行读出来全部放入列表
f = open('a.txt','r',encoding='utf-8')
print(f.readlines(),end='')	# 把所有内容都打印出来

在这里插入图片描述

写入文件的常用方法

可根据自身需要的方式写入文件

常规写法

f = open('a.txt','w',encoding='utf-8')
f.write('123\n456')	# 全部写在一个引号内,不客观
f.close()

多个内容同时写入

f = open('a.txt','w',encoding='utf-8')
f.writelines(['123\n','456\n','789'])	# 引入列表写入多个内容
f.close()

修改文件的流程结构


原理与计算机对文件的操作大致相同

改变文件内容的流程 第一种:
# 1、先将原文件读入内存
# 2、在内存对文件的内容进行修改
# 3、将内存写好的内容覆盖进去

with open('a.txt', 'r', encoding='utf-8') as f:
    data = f.read()
    print('查看文件改动前:')
    print(data) # 查看改动之前

    # 获取文件内容,将特定字符进行替换,这里将jack 替换成 tom
    res = data.replace('jack', 'tom')
    print('='*15)
    
with open('a.txt', 'w+', encoding='utf-8') as f:

    print('文件改动后:')
    f.write(res)  # 将写好的内容覆盖进源文件

    f.seek(0)   # 移动指针到开头
    print(f.read()) # 查看改动之后

# 这种方式对内存造成过分占用,因为需要一次性将源文件全部读入内存

执行代码后,由于计算机运行过快,导致我们看到的就是只是修改了部分内容,其实执行的是覆盖操作,可以看到 jack 已经变成 tom

代码执行效果

在这里插入图片描述

改变文件内容的流程 第二种:
import os
# 修改文件内容的流程 第二种:
# 1、创建一个用于交换文件
# 2、一行行读取源文件的内容到内存
# 3、将内存的文件内存进行操作,再一行行写入交换文件
# 4、删除源文件,将交换文件改成和源文件名称一样

# 节省内存空间,将文件内容分解读入新的文件,和上面复制图片的原理相同
with open('a.txt','r',encoding='utf-8') as f1,\
     open('.a.txt.swp','w+',encoding='utf-8') as f2:
        print('查看文件改动前:')
        print(f1.read())
        f1.seek(0)  # 进行过read操作,将光标重新移动到行首

        print('='*10)   # 上下隔开
        for line in f1.readlines(): # 读多行内容
            f2.write(line.replace('jack','tom'))

        f2.seek(0)  # 进行过写操作,将光标移动到行首

        print('查看文件改动后:')
        print(f2.read())

os.remove('a.txt')  # 删除源文件
os.rename('.a.txt.swp','a.txt') # 将交换文件名替换成 和原文件相同的名字

执行后效果,与上序效果相同,但底层原理不同:

在这里插入图片描述


演示字符乱码

# 对文件进行写入内容,使用编码为gbk
f = open('a.txt','w',encoding='gbk')
f.write('这是Python基础(3)文件处理')	# 写入中文内容更容易看出效果
f.close()

# 读取文件内容,使用解码为utf-8
f2 = open('a.txt','r',encoding='utf-8')
print(f2.read())
f2.close()

因为这里编辑器设置的是utf-8解码,所以看到的是乱码的内容,并且运行的程序也报错了,因为通过utf-8 无法进行解码

在这里插入图片描述

如果后续打开一个文件出现乱码,不妨调整一下解码格式,这里调整成gbk成功读取到内容

在这里插入图片描述
UTF-8作为国际编码,而GBK是国家编码(太过局限),通用性不高,所以对文件进行处理建议使用UTF-8作为编码标准。如果遇到读取一个文件时产生乱码:两种情况

第一种:

在编码时,输入的字符使用的编码表无法识别,这样在存入硬盘后,直接就是存了一堆乱码,在读出来的内容也是乱码,那么这种情况无法解决,因为起步就错了。

第二种:

没有使用文件在存入硬盘时的编码进行解码,那么对这种情况只能进行尝试多个编码才配对。


with 上下文管理,这里使用with 用来管理open


# as 后面定义一个别名,通过这个别名来访问文件对象
with open('a.txt','r',encoding='utf-8') as f:
	print(f.read())
	# 使用完以后不用执行close操作,因为with会在我们使用完文件时会帮我们关闭文件
123



# 同时打开多个文件
# \表示转义符,意思是经过转义符后的内容还是属于同一行的,这样用于更加可观
# 如果不加转义符,那么会出现语法错误
with open('a.txt','r',encoding='utf-8') as f1,\	# 表示后面还有内容
	 open('b.txt','w',encoding='utf-8') as f2:	# 记得冒号
		
		print(f1.read())	# 读取文件a内容
		print(f2.write('456'))	# 新建文件b写入内容
123

# 不用担心占用系统资源,可同时管理多个文件

练习:循环创建文件并写入内容

words = 'abcdefghijklmnopqrstuvwxyz'    # 定义26个字母

count = 1   # 进行一个计数
for i in words: # 遍历字符串就是把一个字符都拿过来
	# 一个字母创建一个文件
    with open(i + ".txt",'w',encoding='utf-8') as f:
    	# 第一个就是a1、第二个就是b2
        f.write(i + str(count)) # count转换成字符串类型才能与字符进行连接
    count += 1  # 每次数字加一

练习:循环删除文件,这里提前用到一个库的知识

import  os

words = 'abcdefghijklmnopqrstuvwxyz'
for i in words:	# 循环26的字母
    os.remove(i + '.txt')	# 通过这个库提供的remove方法删除文件

练习:不断往文件写入内容

import time

with open('success.txt','a',encoding='utf-8') as f:
    while True:
        print('正在写入内容:GoodMorning')
        f.write('GoodMorning\n')
        time.sleep(0.5)	# 写入一次以后,使用这个模块暂停0.5秒钟
        
    	'''
    	因为当前进程运行过程中往硬盘写入时,并没有立马写入进去,会被缓存起来,等待缓存很多以后再一次性写进去。
    	
    	所以我们执行flush不对其进行缓存,立马写入进去。
    	'''
        f.flush()

练习:实时监测文件添加的内容

import time
with open('success.txt','r') as f:
    f.seek(0,2)
    print('正在检测文件:success')
    while True:
        line = f.readline()	# 每次读取文件一行内容
        
        # 如果没有内容就暂停0.1秒钟,注意:这0.1对计算机来是一个缓解压力的时间
        # 不然死循环,会很大消耗计算机资源
        if len(line) == 0:
            time.sleep(0.1)
        else:	# 如果有内容就打印出来,不换行,因为写入时已经有换行
            print('success文件新增了一行内容:',line,end='')

下一篇博客 函数:https://blog.csdn.net/m0_46958731/article/details/110121539

技术小白记录学习过程,有错误或不解的地方请指出,如果这篇文章对你有所帮助请点赞收藏+关注 谢谢支持!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值