Python的文件处理

一 引入

应用程序运行过程中产生的数据最先都是存放于内存中的,若想永久保存下来,必须要保存于硬盘中。应用程序若想操作硬件必须通过操作系统,而文件就是操作系统提供给应用程序来操作硬盘的虚拟概念,用户或应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作。

二 文件操作的基本流程

 

2.1 基本流程

有了文件的概念,我们无需再去考虑操作硬盘的细节,只需要关注操作文件的流程:

	"""
		三步法:
			1. 打开文件(open)
			2. 读或者写
			3. 关闭文件
	"""

# open('要操作的文件路径', '读写模式', '字符编码')   


# 1. 打开文件,由应用程序向操作系统发起系统调用open(...),操作系统打开该文件,对应一块硬盘空间,并返回一个文件对象赋值给一个变量f
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r

# 2. 调用文件对象下的读/写方法,会被操作系统转换为读/写硬盘的操作
data=f.read()

# 3. 向操作系统发起关闭文件的请求,回收系统资源
f.close()

文件对象: 

 Python的文件处理_第1张图片

 

2.2 资源回收与with上下文管理

打开一个文件包含两部分资源:应用程序的变量f和操作系统打开的文件。在操作完毕一个文件时,必须把与该文件的这两部分资源全部回收,回收方法为:

f.close() #回收操作系统打开的文件资源
del f #回收应用程序级的变量

其中del f一定要发生在f.close()之后,否则就会导致操作系统打开的文件无法关闭,白白占用资源,而python自动的垃圾回收机制决定了我们无需考虑del f,这就要求我们,在操作完毕文件后,一定要记住f.close(),虽然我们如此强调,但是大多数读者还是会不由自主地忘记f.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)

 

三 文件的操作模式 

3.1 控制文件读写操作的模式

 读写模式:
        r         (只读:只能读不能写)  

        w        (只写:只能写,不能读)    

        a         (append:在原来的基础之上在添加新的内容)

 

3.1.1 案例一:r 模式的使用 

# 1. 只读模式

"""当文件路径不存在的时候,会直接保存"""
f = open('b.txt', 'r', encoding='utf-8') #  No such file or directory: 'b.txt'
f = open('a.txt', 'r', encoding='utf-8') #  No such file or directory: 'b.txt'
print(f.read())
f.close()

with open('a.txt', 'r', encoding='utf-8') as f:
    print(f.read())

3.1.2 案例二:w 模式的使用

"""
写模式的特征: 
    1. 当文件路径不存在的时候, 会新建出来一个文件,而不报错
    2. 写模式会把原来的数据覆盖掉,从新写入新的数据(重要)
"""

with open('b.txt', 'w', encoding='utf-8') as f:
    f.write('hello')
    f.write('hahahahhah')
    f.write('jerry')

3.1.3 案例三:a 模式的使用 

"""
追加模式:当路径不存在的时候,也会新建出来文件
    记住:它是追加写,而不是覆盖原来的内容!
"""

with open('c.txt', 'a', encoding='utf-8') as f:
    f.write('hello world')
    f.write('hello world1')
    f.write('hello world2')
    f.write('hello world3')
    f.write('hello world4')
    f.write('hello world5')

 

 3.1.4 案例四:+ 模式的使用(了解)

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

3.2 控制文件读写内容的模式 

大前提: tb模式均不能单独使用,必须与r/w/a之一结合使用


t(默认的):文本模式
    1. 读写文件都是以字符串为单位的
    2. 只能针对文本文件
    3. 必须指定encoding参数


b:二进制模式:
   1.读写文件都是以bytes/二进制为单位的
   2. 可以针对所有文件
   3. 一定不能指定encoding参数

 

3.2.1 案例一:t 模式的使用 

# t 模式:如果我们指定的文件打开模式为r/w/a,其实默认就是rt/wt/at
 with open('a.txt',mode='rt',encoding='utf-8') as f:
     res=f.read() 
     print(type(res)) # 输出结果为:
        
 with open('a.txt',mode='wt',encoding='utf-8') as f:
     s='abc'
     f.write(s) # 写入的也必须是字符串类型
    
 #强调:t 模式只能用于操作文本文件,无论读写,都应该以字符串为单位,而存取硬盘本质都是二进制的形式,当指定 t 模式时,内部帮我们做了编码与解码

 

3.2.2 案例二: b 模式的使用

# b: 读写都是以二进制位单位
 with open('1.mp4',mode='rb') as f:
     data=f.read()
     print(type(data)) # 输出结果为:

 with open('a.txt',mode='wb') as f:
	 msg="你好"
     res=msg.encode('utf-8') # res为bytes类型
     f.write(res) # 在b模式下写入文件的只能是bytes类型

# 强调:b模式对比t模式
1、在操作纯文本文件方面t模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以此时t模式更为方便
2、针对非文本文件(如图片、视频、音频等)只能使用b模式

 

四 操作文件的方法 

 

4.1 重点

4.1.1 读系列 

# 读系列
    with open('a.txt', 'r', encoding='utf-8') as f:
        print(f.read()) # read方法是一次性读取文件中得所有数据
        print(f.readline()) # helloworld1
        print(f.readline()) # readline一次只读文件的一行内容
        print(f.readlines()) # 一次性读取文件的所有内容,然后每一个内容作为列表的一个元素返回,返回的数据类型是:列表
        print(f.readable()) # able ation un multi ...	

4.1.2 写系列

f.write('1111\n222\n')  # 针对文本模式的写,需要自己写换行符
f.write('1111\n222\n'.encode('utf-8'))  # 针对b模式的写,需要自己写换行符
f.writelines(['333\n','444\n'])  # 文件模式
f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式

 

4.2 了解

f.readable()  # 文件是否可读
f.writable()  # 文件是否可读
f.closed  # 文件是否关闭
f.encoding  # 如果文件打开模式为b,则没有该属性
f.flush()  # 立刻将文件内容从内存刷到硬盘

 

运用文件知识的小练习:

 1. 写一个简易版本的注册和登录功能

# 1. 注册功能

# 1.需要用户名和密码
username = input('username:').strip()
password = input('password:').strip()

# 2. 组织成特殊的格式保存在文件里
# jerry|123
data = '%s|%s' % (username, password)

# 3. 直接写数据到文件里
with open('userinfo.txt', 'w', encoding='utf-8') as f:
    """写文件的时候,写入的数据类型必须是字符串和二进制"""
    f.write(data) # write() argument must be str, not int
print('%s注册成功' % username) 






# 2.单用户的登录功能
# 1. 让用户输入用户名和密码
username = input('username:>>>').strip()
password = input('password:>>>').strip()

# 2. 需要读取文件,然后切割字符串,拿到真实的用户名和真实的密码,最后做比较
with open('userinfo.txt', 'r', encoding='utf-8') as f:
    # 由于目前文件中得数据比较少,所以可以一次性读取
    data = f.read()

'''with子代码块中得代码是可以直接在外面使用的'''
# data:jerry|123
# 可以直接使用解压赋值拿到真实的有用户名和密码
real_username, real_password = data.split('|')
# res = data.split('|')

# 3. 比较用户名和密码是否正确
if username == real_username and password == real_password:
    print('登录成功')
else:
    print('用户名或者密码错误')  

 

2.多用户的注册功能和多用户数据情况下的登录功能

# 1.多用户的注册功能

while True:
    # 1. 用户输入用户名和密码
    username = input('username:').strip()
    password = input('password:').strip()

    '''我们需要验证用户名是否已经存在?'''
    # 4. 读取文件内的数据,然后一行一行拿到每个用户名,然后做比较
    with open('userinfo.txt', 'r', encoding='utf-8') as f:
        # 逐行读取数据
        for line in f:
            # line:kevin|123
            real_username, real_password = line.split('|') #
            # 判断
            if real_username == username:
                print('用户名已经存在')
                break
        else:
            # 2. 组织数据成特殊的格式
            data = '%s|%s\n' % (username, password)

            # 3. 把用户名和密码写入到文件中
            with open('userinfo.txt', 'a', encoding='utf-8') as f:
                f.write(data)
            print('%s 注册成功' % username)




# 2.多用户的登录功能

with open('userinfo.txt', 'r', encoding='utf-8') as f:
    # read readline
    # 循环逐行读取用户名和密码
    for line in f:
        # line : jerry|123
        real_username, real_password = line.split('|') # ['jerry', '123\n']
        # print(real_username, real_password)
        # 比较用户名和密码
        if real_username == username and password == real_password.strip('\n'):
            print('登录成功')
            break
        else:
            print('用户名或者密码不正确')

 

 3.多用户登录和注册的整合

"""
代码启动之后,给用户展示功能编号
    1. 注册功能
    2. 登录功能
"""


while True:
    print("""
        1. 注册功能
        2. 登录功能
    """)

    cmd = input('请输入你要执行的功能编号:').strip()
    if not cmd.isdigit():continue
    if cmd == '1':
        while True:
            # 1. 用户输入用户名和密码
            username = input('username:').strip()
            password = input('password:').strip()

            '''我们需要验证用户名是否已经存在?'''
            # 4. 读取文件内的数据,然后一行一行拿到每个用户名,然后做比较
            with open('userinfo.txt', 'r', encoding='utf-8') as f:
                # 逐行读取数据
                for line in f:
                    # line:kevin|123
                    real_username, real_password = line.split('|')  #
                    # 判断
                    if real_username == username:
                        print('用户名已经存在')
                        break
                else:
                    # 2. 组织数据成特殊的格式
                    data = '%s|%s\n' % (username, password)

                    # 3. 把用户名和密码写入到文件中
                    with open('userinfo.txt', 'a', encoding='utf-8') as f:
                        f.write(data)
                    print('%s 注册成功' % username)

    elif cmd == '2':
        username = input('username:>>>').strip()
        password = input('password:>>>').strip()
        # 2. 读取文件的数据比较密码
        with open('userinfo.txt', 'r', encoding='utf-8') as f:
            # read readline
            # 循环逐行读取用户名和密码
            for line in f:
                # line : jerry|123
                real_username, real_password = line.split('|') # ['jerry', '123\n']
                # print(real_username, real_password)
                # 比较用户名和密码
                if real_username == username and password == real_password.strip('\n'):
                    print('登录成功')
                    break
                else:
                    print('用户名或者密码不正确')
    

你可能感兴趣的:(Python基础,python,前端,javascript,数据结构,算法)