python:从入门到放弃 06 文件处理

什么是文件

在进行文件处理之前,我们需要知道是什么是文件,文件即操作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作。

文件处理流程

1.打开文件、创建文件
2.编辑文件内容
3.保存文件内容
4.关闭文件

文件的打开与关闭

f = open()  # 打开
f = close() # 关闭

1.使用关键字打开文件
open(r'a.txt')  # 相对路径
open(r'D:\py1\day09\a.txt')  # 绝对路径
res = open(r'a.txt', 'r', encoding='utf8')
'''
open(文件的路径,文件的操作模式,文件的编码)
1.文件的路径是必须要写的
2.文件的操作模式、文件的编码有时候不用写
'''
在处理完文件后,我们需要使用close()关闭文件,然而这一个步骤非常的容易遗忘掉。
考虑到这一点,python提供了with关键字来帮我们管理上下文
# 1、在执行完子代码块后,with 会自动执行f.close()
with open('a.txt','w') as f:
	pass 

# 2、可用用with同时打开多个文件,用逗号分隔开即可
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:  
	data = read_f.read()
	write_f.write(data)

文件的读写模式

r	read	只读模式:只能读不能写
w	write	只写模式:只能写不能读
a   append   只追加模式:在文件末尾添加内容

r模式

# r只读模式: 在文件不存在时则报错,文件存在文件内指针直接跳到文件开头
 with open('a.txt',mode='r',encoding='utf-8') as f:
     res=f.read() # 会将文件的内容由硬盘全部读入内存,赋值给res

w模式

# w只写模式: 在文件不存在时会创建空文档,文件存在会清空文件,文件指针跑到文件开头
with open('b.txt',mode='w',encoding='utf-8') as f:
    f.write('你好\n')
    f.write('我好\n') 
    f.write('大家好\n')
    f.write('111\n222\n333\n')
#强调:
# 1 在文件不关闭的情况下,连续的写入,后写的内容一定跟在前写内容的后面
# 2 如果重新以w模式打开文件,则会清空文件内容

a模式

# a只追加写模式: 在文件不存在时会创建空文档,文件存在会将文件指针直接移动到文件末尾
 with open('c.txt',mode='a',encoding='utf-8') as f:
     f.write('44444\n')
     f.write('55555\n')
#强调 w 模式与 a 模式的异同:
# 1 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
# 2 不同点:以 a 模式重新打开文件,不会清空原文件内容,会将文件指针直接移动到文件末尾,新写的内容永远写在最后

+模式

r+ w+ a+ :可读可写

在平时工作中,我们只单纯使用r/w/a,要么只读,要么只写,一般不用可读可写的模式*

文件的操作模式

t模式

文本模式 是默认的模式
    	r	rt
        w	wt
        a	at
    1.该模式只能操作文本文件
    2.该模式必须要指定encoding参数
    3.该模式读写都是以字符串为最小单位

b模式

二进制模式  可以操作任意类型的文件
    	rb  不能省略b
        wb  不能省略b
        ab  不能省略b
    1.该模式可以操作任意类型的文件
    2.该模式不需要指定encoding参数
    3.该模式读写都是以bytes类型为最小单位

文件的内置方法

# 读操作
.read()  # 读取所有内容,执行完该操作后,文件指针会移动到文件末尾
.readline()  # 读取一行内容,光标移动到第二行首部
.readlines()  # 读取每一行内容,存放于列表中
.readable()  # 判断当前文件是否可读
# 强调:
# f.read()与f.readlines()都是将内容一次性读入内容,如果内容过大会导致内存溢出,若还想将内容全读入内存,则必须分多次读入,有两种实现方式:
# 方式一
with open('a.txt',mode='rt',encoding='utf-8') as f:
    for line in f:
        print(line) # 同一时刻只读入一行内容到内存中

# 方式二
with open('1.mp4',mode='rb') as f:
    while True:
        data=f.read(1024) # 同一时刻只读入1024个Bytes到内存中
        if len(data) == 0:
            break
        print(data)
        
# 写操作
.write('1111\n222\n')  # 针对文本模式的写,需要自己写换行符
.writelines(['333\n','444\n'])  # 文件模式
.writable()  # 判断文件是否可写
.flush()  # 相当于主动按了ctrl+s(保存)  

主动控制文件内光标移动

#大前提:文件内指针的移动都是Bytes为单位的,唯一例外的是t模式下的read(n),n以字符为单位
with open(r'a.txt','r',encoding='utf8') as f:
    print(f.read(3))
    print(f.read(3))
# read在二进制模式下 括号内的数字表示的是读取指定的字节数
with open(r'a.txt', 'rb') as f:
    print(f.read(9).decode('utf8'))
    print(f.read(1).decode('utf8'))
    
    
.seek(offset,whence) # offset:控制移动的字节数 whence:控制模式
'''
0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
1: 该模式代表指针移动的字节数是以当前所在的位置为参照的
2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的
强调:其中0模式可以在t或者b模式使用,而1跟2模式只能在b模式下用
 '''

文件的修改

# 文件a.txt内容如下
张一蛋     山东    179    49    12344234523
李二蛋     河北    163    57    13913453521
王全蛋     山西    153    62    18651433422

# 执行操作
with open('a.txt',mode='r+t',encoding='utf-8') as f:
    f.seek(9)
    f.write('<妇女主任>')
    
# 文件修改后的内容如下
张一蛋<妇女主任> 179    49    12344234523
李二蛋     河北    163    57    13913453521
王全蛋     山西    153    62    18651433422

实际上,我们并不能修改在硬盘上的数据,所以我们将硬盘中文件内容读入内存,然后在内存中修改完毕后再覆盖回硬盘。具体的实现方式有2种。

文件修改方式一

# 实现思路:将文件内容发一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
# 优点: 在文件修改过程中同一份数据只有一份
# 缺点: 会过多地占用内存
with open('db.txt',mode='rt',encoding='utf-8') as f:
    data=f.read()

with open('db.txt',mode='wt',encoding='utf-8') as f:
    f.write(data.replace('kevin','SB'))

文件修改方式二

# 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件...,删掉原文件,将临时文件重命名原文件名
# 优点: 不会占用过多的内存
# 缺点: 在文件修改过程中同一份数据存了两份
import os

with open('db.txt',mode='rt',encoding='utf-8') as read_f,\
        open('.db.txt.swap',mode='wt',encoding='utf-8') as wrife_f:
    for line in read_f:
        wrife_f.write(line.replace('SB','kevin'))

os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')

小作业

1.编写一个简易版本的拷贝程序
	路径全部自定义
file_path = input(r'输入文件的路径>>>>')
with open(r'test.txt', 'r', encoding='utf8') as test1:
    ste = test1.read()
with open(file_path, 'a', encoding='utf8') as test2:
    test2.write(ste)
2.结合文件编写用户注册登录功能
	# 提前先创建一个空的userinfo.txt
	用户注册 数据保存到文件中
    用户登录 数据来源于文件
    1.必须给我写出来
    	单用户注册登录
    2.拔高练习
    	多用户注册登录
while True:
    print('1.注册 2.登录')
    inp = input('输入编号选择功能')
    if inp == '1':
        username_inp = input('请输入用户名>>>')
        password_inp = input('请输入密码>>>')
        user_str = username_inp + '|' + password_inp + '\n'
        with open(r'userinfo.txt', 'a', encoding='utf8') as test:
            test.write(user_str)
    if inp == '2':
        username_inp = input('请输入用户名>>>')
        password_inp = input('请输入密码>>>')
        user_str = username_inp + '|' + password_inp + '\n'
        with open(r'userinfo.txt', 'r', encoding='utf8') as test:
            for i in test:
                if i == user_str:
                    print('登录成功')
                    break
            else:
                print('登录失败')
posted @ 2022-03-14 21:05  Rain_Kz  阅读(33)  评论(0编辑  收藏  举报