文件的基本操作

文件的基本操作

1. 我们能够操作哪些类型的文件:
    .txt 没有后缀名的文件
    # 我们现在不能操作word、Excel、PPT等文件暂时不能够操作
    numpy、pandas等模块可以操作
2. 如何操作文件
    """
        三步法:
            1. 打开文件(open)
            2. 读或者写
            3. 关闭文件
    """
# open('要操作的文件路径', '读写模式', '字符编码')   
文件的路径:
    相对路径
    绝对路径
    'D:\Python27\day10\a.txt'
    # 当路径中出现了字母和斜杠的组合会产生一些特殊的含义,所以我们应该给去掉:
    r'D:\Python27\day10\a.txt'
f= open(r'D:\Python27\day10\a.txt', 'r', encoding='utf-8')  # \n \t
# 返回的是文件句柄
print(f) # <_io.TextIOWrapper name='D:\\Python27\\day10\\a.txt' mode='r' encoding='utf-8'>

# 2. 读取文件
# helloworld
print(f.read()) # 类似于是文件的内置方法

# 3. 关闭文件
f.close()


'''第二种方式来操作文件'''
# with上下文管理器打开文件!
# as:起别名
# 它的特点就在于:能够自动关闭文件
with open('a.txt', 'r', encoding='utf-8') as f: # f=open('a.txt', 'r', encoding='utf-8')  f.close()
    print(f.read())

文件的读写模式

"""
    语法格式:
        open(文件路径,读写模式,字符编码)
        文件路径:是必须写的
        读写模式:也是必须写的
        字符编码:可选的
"""
读写模式:
    r(只读:只能读不能写)   w(只写:只能写,不能读)    a(append:在原来的基础之上在添加新的内容)

1. 只读模式
# 1. 读模式
"""当文件路径不存在的时候,会直接保存"""
# f = open('b.txt', 'r', encoding='utf-8') 
# f = open('a.txt', 'r', encoding='utf-8') 
# print(f.read())
# f.close()

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


# 2. 写模式
"""写模式的特征: 
    1. 当文件路径不存在的时候, 会新建出来一个文件,而不报错
    2. 写模式会把原来的数据覆盖掉,从新写入新的数据(重要)
"""
# with open('b.txt', 'w', encoding='utf-8') as f:
#     # pass # 为了不全语法结构
#     # f.write('hello')
#     # f.write('hahahahhah')
#     f.write('jerry')


# 3. 追加模式
"""追加模式:当路径不存在的时候,也会新建出来文件
    记住:它是追加写,而不是覆盖原来的内容!
"""
with open('c.txt', 'a', encoding='utf-8') as f:
    f.write('hello world')

读写操作相关的方法

1. 读系列
    # 读系列
    with open('a.txt', 'r', encoding='utf-8') as f:
        # print(f.read()) # read方法是一次性读取文件中得所有数据
        # print(f.readline()) 
        # print(f.readline()) # readline一次只读文件的一行内容
        # print(f.readlines()) # 一次性读取文件的所有内容,然后每一个内容作为列表的一个元素返回,返回的数据类型是:列表
        print(f.readable()) 
2. 写系列
    # 写系列
    ### 做后端程序员:最重要的是安全意识
    with open('a.txt', 'w', encoding='utf-8') as f:
        # f.write('jerry say hello ')
        # f.writelines(['hello\n', 'jerry\n', 'kevin\n', 'jason\n'])
        print(f.writable())
        print(f.readable())    

文件的读操作优化

with open('a.txt', 'r', encoding='utf-8') as f:
    # print(f.read()) # 一次性读取文件的所有数据,并且光标在文件的末尾,如果在去读,就读不到了
    # print(f.read())
    # 文件句柄f是支持for循环的
    for line in f:
        # line: 就是文件的一行内容
        print(line)
    # 了解的方法:
    # f.flush()  # 把数据从内存中立刻刷到磁盘
    """
        当你读取的数据比较小的时候,其实是在缓冲区的,当数据量够多的时候,它会一定刷到磁盘
    """
"""
一次性读取文件的所有数据有什么问题:
    当数据比较多的时候,会出现内存溢出,这种情况是坚决不能出现的
    如何优化以上操作:
        一点一点的读取数据然后把数据赶紧刷到硬盘里
        
"""

多用户的注册


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)

多用户登录

#  读取文件的数据比较密码
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('|') 
        # 比较用户名和密码
        if real_username == username and password == real_password.strip('\n'):
            print('登录成功')
            break
        else:
            print('用户名或者密码不正确')

多用户注册登录

"""
代码启动之后,给用户展示功能编号
    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('用户名或者密码不正确')
    

文件的操作模式

1. 文本模式 
    t:text
    # r w a =====> rt wt at
    """
        with open('userinfo.txt', 'r', encoding='utf-8') as f:
        文本模式默认就是操作字符串,文本
        特征:
            1. encoding参数必须指定
            2. 读取的所有的数据都是以字符串为单位的
            3. t模式只能够读取文本或者字符模式
    """
2. 二进制模式
    b模式:binary
    with open('userinfo.txt', 'rb') as f:
    """
        b模式中得b不能省略------------> rb wb ab
        特征:
            1. encoding='utf-8'参数不能够指定
            2. 读取的数据全部以字节为单位
            3. 二进制模式可以读取任意类型的文件
    """

二进制模式下读写操作

# with open('a.txt', 'r', encoding='utf-8') as f:
#     print(f.read(5))
​
​
with open('a.txt', 'rb') as f:
    # print(f.read().decode('utf-8')) # b'helloworld'
    print(f.read(7).decode('utf-8')) # b'helloworld'
"""
t模式下:
    f.read() 如果不指定参数,默认情况下是一次性读取所有
    f.read(5) 如果指定了参数,返回的就是字符个数
    
b模式下:
    f.read(5) 如果指定了参数,返回的就是字节个数
    如果文件中有中文字符,切记书写的数字要是3的倍数,如果有中文也有英文字符,这个数字需要计算了
"""

控制文件内指针的移动

指针:就可以理解成光标的移动
# with open('a.txt', 'r', encoding='utf-8') as f:
#     print(f.read(5)) # 你helloworld
#     f.seek(3, 1)
#     print(f.read())
#     # print(f.read(5))
#     # print(f.read())
​
with open('a.txt', 'rb') as f:
    print(f.read(2))  # helloworld
    f.seek(-3, 2)
    print(f.read())
    # print(f.read(5))
    # print(f.read())
​
"""
f.seek()
    offset: int,
        代表的是移动的偏移量
        如果是正数,就往右边移
        如果是负数,就往左边以----------》左边要可移动
    whence: int = 0
        代表的是模式
        # 模式控制:
        
        # 0: 默认的模式,该模式代表指针移动的字节数是以文件开头为参照的: 它能够使用在t和b模式
        # 1: 该模式代表指针移动的字节数是以当前所在的位置为参照的: 只支持b模式,t模式不行
        # 2: 该模式代表指针移动的字节数是以文件末尾的位置为参照的
"""
​
​

# 小练习:实现动态查看最新一条日志的效果
import time  # 导入的一个时间模块
​
# linux里面的一条命令:tail -f access.log
with open('access.log', mode='rb') as f:
    f.seek(0, 2)
    while True:
        line = f.readline()
        if len(line) == 0:
            # 没有内容
            time.sleep(0.5) # 睡眠0.5秒
        else:
            print(line.decode('utf-8'), end='')

文件的修改

with open('a.txt',mode='r+t',encoding='utf-8') as f:
      f.seek(9)
      f.write('<妇女主任>')
mode='r+'    
mode='w+t'
mode='a+t'
# 可读可写
# 可读可写
# 可读可写
​
1. 硬盘中得数据是不允许直接修改的
2. 内存中得数据是可以直接修改的
​
'''方式一:'''
# 1. 读取文件内的所有数据
# 快捷键:shift+enter
with open('a.txt', 'r', encoding='utf-8') as f:
    data = f.read()
​
print(data)
​
# 2. 读取完字符之后,做字符替换
with open('a.txt', 'wt', encoding='utf-8') as f:
    f.write(data.replace('kevin', 'kevinSB'))
    
'''方式2:'''
import os
​
with open('a.txt',mode='rt',encoding='utf-8') as read_f, \
        open('.a.txt.swap',mode='wt',encoding='utf-8') as wrife_f:
    for line in read_f:
        wrife_f.write(line.replace('SB','kevin'))
​
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')




# 小练习: 编写拷贝工具
    1. 让用户输入被拷贝的文件路径(源文件路径)
    2. 输入即将要拷贝的文件路径(目标文件路径)
    3. 以读的模式打开源文件,以写的模式打开目标文件
    
# 1. 先有源文件的路径
source_file_path = input('请输入待拷贝的文件路径:').strip()

# 2. 写一个即将要拷贝的文件路径

dst_file_path = input('请输入目标文件的路径:').strip()

# 3. 以r模式打开源文件,以写模式打开目标文件
with open(r'%s' % source_file_path, 'rb') as read_f:
    with open(r'%s' % dst_file_path, 'wb') as write_f:
        for line in read_f:
            write_f.write(line) 
    
posted @ 2023-09-04 15:14  橙子先生呀  阅读(14)  评论(0编辑  收藏  举报  来源