文件相关操作

1.文件操作

1.文件的概念
	就是操作系统暴露给用户操作硬盘的快捷方式,双击一个文件就是将硬盘中的数据加载到内存,保存文件就是将内存中的数据刷到硬盘
    
2.代码打开文件的两种方式:
    方式1: 不推荐,因为close关键字经常被忘记
        f = open(文件路径,读写模式, encoding= 'utf8')
        f.close()  # 保存文件
    方式2:
    	  with open(r'a.txt', 'r', encoding='utf8')as f1:
            with子代码块
     方式2好处在于子代码运行结束后自动调用close方法关闭资源
    
"""
注意:
1.open方法第一个参数是文件路径,并且\跟一些字母组合产生特殊含义导致文件路径查找混乱,为了解决混乱可以在字符串前面加上r。
	D:\a\n\t
	r'D:\a\n\t'
	
2.with支持一次性打开多个文件:
	with open() as f1, open() as f2:
		子代码
"""

2.文件读写模式

1.r:只读模式:只能读不能写
	1.1:文件路径不存在:会直接报错
   with open (r'a.txt', 'r', encoding='utf8') as f1:
    	print(f1.read())
	1.2文件路径存在:正常读取文件内容
   with open(r'a','r', encoding='utf8') as f1:
    print(f1.read())
    
2.w:只写模式:只能写不能看
	2.1文件路径不存在:自动创建
   with open(r'b.txt', 'w', encoding='utf8') as f2:
    f2.write('十一过得快吗\n真快')  
    
	2.2文件路径存在:先清空文件内容,之后再写入
	with open(r'b.txt', 'w', encoding='utf8') as f2:
    f2.write('假期综合征\n需要尽快调整')
"""
换行符需要自己添加,并且作业中数据对比中要注意该问题存在,需要用strip关键字去掉首尾换行符之后做对比
"""

3.a:只追加模式:文件末尾添加数据
	3.1文件路径不存在:自动创建(同w模式)
	with open (r'c.txt', 'a', encoding='utf8') as f3:
    f3.write('a模式文件路径不存在会发生什么呢')
    
	3.2文件路径存在:自动在末尾等待追加内容
"""
关键字:pass
补全语法功能本身并无任何含义,适用于功能搭建阶段
"""

3.文件操作模式

1.文本模式(t模式):
    默认的模式,我们上面写的r,w,a,都是rt,wt,at的简写。
    2.只能操作文本文件
    3.需要制定encoding参数,如果不知道则会采用计算机默认的编码
    
2.二进制模式(b模式或bytes模式)
	不是默认的模式,rb,wb,ab不能简写
    1.可以操作任意类型文件
    2.读写都是以bytes为单位
    3.不需要指定encoding参数,因为它已经是二进制模式了,不需要编码
    
"""
二进制模式和文本模式针对文件路径是否存在的情况规律是一样的
"""

4.文件的相关操作

1.read():一次性读取文件内容,并且目标停留在文件末尾,继续读取则没有内容。并且当文件内容比较多时,该方法可能会造成计算机内存溢出,括号内还可以写数字,在文本模式下表示读取几个字符。
with open (r'c.txt', 'r',encoding='utf8') as f:
    print(f.read())
    print(f.read())
    print(f.read())  # r模式下执行打印三遍read()到底会执行几次呢
"""
三个print最终只执行了一次,因为一次性读取文件内容,鼠标停留在了文档末尾。
"""

image

image

2.for循环:
    一次性只读一行内容,避免因为文件内存过大导致内存溢出
with open (r'b.txt', 'r',encoding='utf8') as f:
    for line in f:
        print(line)
"""
为什么原文件每行没有间隙,pycharm打印出来就有???
	因为for循环之后line中包含了一个换行符(\n),而print()关键字本身也自带换行符,相当于每循环打印一行会有两个换行符。
"""

image

image

3.readline():一次只读一行内容,要想打印多行需要多个print()

image

image

4.readlines():一次性读取文件内容,会把每行内容当做元素组成一个列表,列表中的内容会自带换行符。
   
5.readable:判断文件是否具备读数据的能力

image

6.write():写入数据
    
7.writable():判断文件是否具备写数据的能力
    
8.writelines():接受一个列表,一次性将列表中所有的数据写入

image

image

9.flush():将内存文件中数据立刻刷到硬盘,等价于ctrl + s

5.文件内光标的移动

"""
提问:可读模式下多个print只能打印一遍文件,用什么办法可以执行几遍print就打印几遍文件?

seek()关键字:控制光标的移动
"""

with open(r'b.txt', 'r', encoding='utf8') as f:
    print(f.read())
    f.seek(0, 0)
    print(f.read())
    f.seek(0, 0)
    print(f.read())
    
"""
seek(offset, whence)
	offset是位移量
	whence是模式
		0:基于文件开头,文本模式和二进制模式都可以使用
		1:基于当前位置,只有二进制模式可以使用
		2:基于文件末尾:只有二进制模式可以使用
"""
with open(r'b.txt', 'r', encoding='utf8') as f:
    print(f.read())
    f.seek(5, 0)  # 光标往后移动5个字节,1个字母占一个字节,1个汉字占3个字节
    print(f.read())
    
with open(r'b.txt', 'r', encoding='utf8') as f:
    print(f.read())
    f.seek(4, 0)  # 字母占2个字节,汉字占3个字节,无法构成一个汉字
    print(f.read())

r模式下多次打印一个文件
image

image

seek()关键字
image

image

image

6.文件内光标移动

监测文档是否变化练习题:
import time

with open(r'a.txt', 'rb') as f:
    f.seek(0, 2)
    while True:
        line = f.readline()
        if len(line) == 0:
            # 没有内容
            time.sleep(0.5)
        else:
            print(line.decode('utf8'), end='')

7.计算机硬盘修改数据原理

硬盘写数据可以看成是在硬盘上刻字,一旦需要修改中间内容,则需要重新刻字,因为刻过得字不可能从中间分开再写。

硬盘删除数据的原理:
    不是直接删除而是改变状态,灯带后续数据覆盖之后才会被真正删除。

8.文件内容修改

方式1:覆盖写:直接在文件中的某个部分讲新的内容覆盖掉原内容
	关键字:replace(),里面的两个参数分别表示替换前的内容和想要替换的内容。
with open(r'a.txt', 'r', encoding='utf8') as f1:
    data = f1.read()
with open(r'a.txt', 'w', encoding='utf8') as f2:
    f2.write(data.replace('danny', 'jenny'))

image

image

image

方式2:换地方写:先在另外一个地方写入内容,然后将源文件删除,将新文件命名成源文件
import os

with open('a.txt', 'r', encoding='utf8') as read_f, \
        open('.a.txt.swap', 'w', encoding='utf-8') as write_f:
    for line in read_f:
        write_f.write(line.replace('tony', 'kevinSB'))
        
        
os.remove('a.txt')  # 删除a.txt
os.rename('.a.txt.swap', 'a.txt')  # 重命名文件

9.作业

'''
1.编写简易版本的拷贝工具
     自己输入想要拷贝的数据路径 自己输入拷贝到哪个地方的目标路径
     任何类型数据皆可拷贝
     ps:个别电脑C盘文件由于权限问题可能无法拷贝 换其他盘尝试即可
'''
source_path = input('请输入拷贝文件的源路径>>>:')
target_path = input('请输入拷贝文件的目标路径>>>:')
with open(r'%s' % source_path, 'rb') as f1:
    data = f1.read()
with open(r'%s' % target_path,'wb') as f2:
    f2.write(data)
	
'''
2.利用文件充当数据库编写用户登录、注册功能
  文件名称:userinfo.txt
  基础要求:
  		 用户注册功能>>>:文件内添加用户数据(用户名、密码等)
       用户登录功能>>>:读取文件内用户数据做校验
      ps:上述功能只需要实现一次就算过关(单用户) 文件内始终就一个用户信
'''
# 基础要求
print("""
    1.注册
    2.登陆
""")
choice = input('请输入您的选项>>>:').strip()
if choice == '1':
    user_name = input('请输入您注册的用户名>>>:').strip()
    user_pdw = input('请输入您注册的密码>>>:').strip()
    user_data = f'{user_name}|{user_pdw}'
    with open(r'user.info(单用户).txt', 'w', encoding='utf8') as f1:
        f1.write(user_data)
        print(f'用户{user_name}注册成功')
elif choice == '2':
    load_name = input('请输入您的用户名>>>:')
    load_pwd = input('请输入您的密码>>>:')
    with open (r'user.info(单用户).txt', 'r', encoding='utf8') as f2:
        data = f2.read()
        real_name, real_pwd = data.split('|')
        if load_name == real_name and load_pwd == real_pwd:
            print('登陆成功')

# 拔高练习
while True:
    print("""
        1.注册
        2.登陆
    """)
    choice = input('请输入您的任务编号>>>:').strip()
    if choice == '1':
        user_name = input('请输入您的用户名>>>:').strip()
        user_pwd = input('请输入您的密码>>>:').strip()
        with open (r'userinfo(多用户).txt', 'r', encoding='utf8') as f1:
            for line in f1:
                if user_name == line.split('|')[0]:
                    print(f'用户{user_name}已注册')
                    break
            else:
                user_data = f'{user_name}|{user_pwd}\n'
                with open (r'userinfo(多用户).txt', 'a', encoding='utf8') as f2:
                    f2.write(user_data)
                    print(f'用户{user_name}注册成功')
    elif choice == '2':
        load_name = input('请输入您的用户名>>>:').strip()
        load_pwd = input('请输入您的密码>>>:').strip()
        with open (r'userinfo(多用户).txt', 'r', encoding='utf8') as f3:
            for line in f3:  # jason|123\n
                real_name, real_pwd = line.split('|')
                if load_name == real_name:
                    if load_pwd == real_pwd.strip('\n'):
                        print('登陆成功')
                        break
            else:
                print('用户名或密码错误')
    else:
        print('请输入正确编号')

posted @ 2023-04-24 20:27  ERROR404Notfound  阅读(79)  评论(0编辑  收藏  举报
Title