006 文件处理

  •   1 # 应用程序运行过程中产生的数据都是存放在内存中的,若想永久保存下来,必须存放在硬盘中
      2 # 应用程序操作硬件必须通过操作系统,而文件就是操作系统提供给应用程序来操作硬盘的虚拟概念
      3 # 用户或者应用程序对文件的操作,就是向操作系统发起调用,然后由操作系统完成对硬盘的具体操作
      4 # 有了文件的概念,我们无需考虑操作硬盘的细节,只需要关注文件操作即可
      5 
      6 # 打开文件,由应用程序向操作系统发起系统调用open(),操作系统打开该文件,对应一块硬盘空间,并返回一个文件对象赋值给一个变量f
      7 f = open('a.txt', 'r', encoding='utf-8')
      8 # 调用文件下的读/写方法,会自动转成硬盘的读/写操作
      9 data = f.read()
     10 # 打印读出来的数据
     11 print(data)
     12 
     13 # 向操作系统发起关闭文件的请求,回收系统资源
     14 f.close()  # 回收变量操作系统打开的文件资源
     15 del f  # 回收应用程序级
     16 print(f)
     17 
     18 # 资源回收和with上下文管理
     19 # 打开一个文件包含两部分资源:应用程序的变量f和操作系统打开的文件。
     20 # 在操作完毕一个文件时,必须把这两部分资源全部回收
     21 # del f 一定要发生在f.close()之后,否则就会导致操作系统打开的文件无法关闭,白白
     22 # 占用资源
     23 
     24 # python自动垃圾回收机制决定了我们无需考虑del f,这就要求我们在操作文笔文件后
     25 # 一定要f.close(),虽然我们如此强调,但是大多数的人还是会忘记f.close()
     26 # 考虑到这一点,python提供了with关键字来帮我们管理上下文
     27 # 可用with打开多个文件,中间用,分隔就行
     28 with open('a.txt', 'r', encoding='utf-8') as read_f, open('b.txt', 'w', encoding='utf-8') as write_f:
     29     res = read_f.read()
     30     write_f.write(res)
     31 
     32 # 指定操作文本文件的字符编码
     33 #
     34 # 由操作系统打开文件,如果打开的是文本文件,则会涉及到字符编码问题,如果没有为open()指定编码,那么打开文本文件的默认编码很明显就是操作系统说了算
     35 # 操作系统会用自己的默认编码去打开文件,在windows下默认是gbk,linux下默认是utf-8。
     36 #
     37 # 要想保证不乱码,怎么存的就怎么取。
     38 # pycharm默认存文件时以utf-8存的,所以取的时候也应该是utf-8,不然会乱码
     39 with open('a.txt', 'r', encoding='gbk') as f:
     40     print(f.read())  # 乱码
     41 
     42 with open('a.txt', 'r', encoding='utf-8') as f:
     43     print(f.read())  # 正常展示
     44 
     45 # 文件的操作模式
     46 # 控制文件读写操作的模式
     47 # r(默认):只读
     48 # w:只写
     49 # a:只追加写
     50 
     51 # r模式的案例使用
     52 # r模式当文件不存在时报错,当文件存在时文件内指针跳到文件开头
     53 with open('a.txt', 'r', encoding='utf-8') as f:
     54     res = f.read()
     55     print(res)
     56 # 哈哈哈哈哈哈
     57 # 呵呵呵呵呵呵
     58 #
     59 # 实现用户登录功能
     60 inp_username = input('请输入你的姓名:').strip()
     61 inp_password = input('请输入你的密码').strip()
     62 
     63 with open(r'property.txt', mode='r', encoding='utf-8') as f:
     64     for line in f:
     65         u, p = line.strip('\n').split(':')
     66         if u == inp_username and p == inp_password:
     67             print('{name}登录成功'.format(name=u))
     68             break
     69         else:
     70             print('用户名或者密码错误,请重新输入')
     71 # w模式的使用
     72 # w只写模式:在文件不存在时创建空文档,文件存在时则清空文件,文件指针跑到文件开头
     73 
     74 with open('c.txt', 'w', encoding='utf-8') as f:
     75     f.write('你好')
     76     f.write('我好')
     77     f.write('大家好好')
     78     f.write('才是\n真的好')
     79 
     80 with open('c.txt', 'w', encoding='utf-8') as f:
     81     f.write('哈哈哈')
     82     f.write('呵呵呵')
     83 
     84 # 在文件不关闭的情况下,连续的写入,后写的内容一定跟在前写内容的后面。
     85 # 如果重新以w模式打开写入,则会清空文件内容
     86 #
     87 # a(只追加写模式)模式的使用:在文件不存在时创建文件,在文件存在时会将文件指针移动到文件末尾
     88 
     89 with open('d.txt','a',encoding='utf-8') as f:
     90     f.write('第一行')
     91     f.write('\n第二行')
     92 
     93 # a模式与w模式的异同:
     94 # 相同点:在打开的文件不关闭的情况下,连续的写入,新写的内容总会跟在前写的内容之后
     95 # 不同点:以a模式重新打开文件,不会清空原文件,会将文件指针移动到文件末尾。新写的内容永远写在最后。
     96 
     97 # a模式实现注册功能
     98 while True:
     99     username = input('请输入你的用户名:')
    100     password = input('请输入你的密码')
    101 
    102     if username == 'quit':
    103         break
    104 
    105     with open('db.txt', 'a', encoding='utf-8') as f:
    106         info = '%s:%s\n' % (username, password)
    107         f.write(info)
    108 
    109 
    110 # +模式的使用
    111 
    112 # r+,w+,a+ 可读可写
    113 
    114 
    115 # 控制文件读写内容的模式
    116 # 大前提:tb模式均不能单独使用,必须与rwa之一结合使用
    117 # t(默认的):文本模式
    118 # 1、读写文件都是以字符串为单位的
    119 # 2、只能针对文本文件
    120 # 3、必须指定encoding参数
    121 
    122 # b:二进制模式
    123 # 1、读写文件都是以bytes/二进制为单位的
    124 # 2、可以针对所有文件
    125 # 3、一定不能指定encoding参数
    126 
    127 # t模式的使用
    128 
    129 with open('test1.txt', 'rt', encoding='utf-8') as f:
    130     res = f.read()
    131     print(res)
    132 
    133 with open('test2.txt', 'wt', encoding='utf-8') as f:
    134     f.write('我写了')
    135     f.write('我写了')
    136     f.write('我写了\n')  # 写入的必须是字符串类型
    137 
    138 with open('test3.txt', 'at', encoding='utf-8') as f:
    139     f.write('测试哈哈哈哈')  # 写入的必须是字符串类型
    140     f.write('测试哈哈哈哈')
    141     f.write('测试哈哈哈哈')
    142     f.write('测试哈哈哈哈')
    143 
    144 # t模式只能用于操作文本文件,无论读写都应该以字符串为单位,而存取硬盘本质都是二进制形式,当指定t模式时,内部
    145 # 已经帮我们做了编码与解码
    146 
    147 # b模式的使用
    148 with open('09 磁盘.mp4','rb') as f:
    149     res = f.read()
    150     print(res)
    151     print(type(res))
    152 
    153 with open('wb.txt', 'wb') as f:
    154     msg = '哈喽呀哈哈哈哈傻逼'
    155     msg_b = msg.encode('utf-8')
    156     f.write(msg_b)  # b模式写入的数据必须是bytes类型
    157 
    158 # 强调:b模式对比t模式
    159 # 在操作纯文本文件方面,t模式帮我们省去了编码与解码的环节,b模式则需要手动编码与解码,所以t模式更加方便
    160 # 针对非文本文件,如(图片、视频、音频),则b模式更加方便
    161 
    162 # 编写拷贝工具
    163 
    164 src_file = input('请输入源文件路径:').strip()
    165 dest_file = input('请输入目标文件路径').strip()
    166 
    167 with open(r'%s' % src_file, 'rb') as read_f, open(r'%s' % dest_file, 'wb') as write_f:
    168     write_f.write(read_f.read())
      1 # 操作文件的方法:
      2 # f.read() 读取所有内容,执行完该操作后文件指针会移动到文件末尾
      3 # f.readline() 读取一行内容,光标移动到第二行的头部
      4 # f.readlines() 读取每一行内容,存放于列表中,光标移动到文件末尾
      5 
      6 # f.read()和f.readlines都是将内容一次性读入,如果内容过大会导致内存溢出,若还想将内容全部读入内存,则必须分多次读入
      7 import time
      8 
      9 with open('xxx1.txt', 'rt', encoding='utf-8') as f:
     10     for line in f:
     11         print(line, end='')  # 以文本内容为例通过for循环每次只读取一行数据
     12 
     13 # with open('09 磁盘.mp4', 'rb') as f:
     14 #     while True:
     15 #         data = f.read(1024)
     16 #         if len(data) == 0:
     17 #             break
     18 #         print(data)
     19 
     20 with open('xxx2.txt', 'at', encoding='utf-8') as f:
     21     f.write('111\n222\n333\n')
     22     f.writelines(['aaa\n', 'bbb\n'])  # 写入多行
     23 
     24 with open('xxx3.txt', 'ab') as f:
     25     f.write('111\n222\n333\n'.encode('utf-8'))
     26     f.writelines([bytes('aaa\n'.encode('utf-8')), bytes('bbb\n'.encode('utf-8'))])
     27 
     28 # 文件是否可读:f.readable
     29 # 文件是否可写:f.writeable
     30 # 文件是否关闭:f.closed
     31 # 文件的编码:f.encoding 如果文件是以b模式打开的,则没有该属性
     32 # 立刻将文件的内容刷新到硬盘 f.flush
     33 # f.name
     34 
     35 # 主动控制文件内指针的移动
     36 # 强调:文件内指针的移动都是以Bytes为单位的,唯一例外的就是t模式下的read(n)方法,是以字符为单位的。
     37 
     38 with open('xxx4.txt', 'rt', encoding='utf-8') as f:
     39     res = f.read(3)
     40     print(res)
     41 
     42 with open('xxx4.txt', 'rb') as f:
     43     res = f.read(3)
     44     print(res.decode('utf-8'))  # 展示了一个字符我,证明我占三个字节
     45 
     46 # 之前文件内指针的移动都是由读写操作被动触发的,若想读取文件某一特定位置的数据,则需要用到f.seek()方法主动控制文件内指针的移动
     47 # f.seek(指针移动的字节数,模式控制)
     48 # 0:默认的模式,该模式代表指针移动的字节数是以文件开头为参照的
     49 # 1:该模式代表指针移动的字节数是以当前所在尾为参照的
     50 #
     51 # # 强调:0模式可以在t或者b中使用,1和2只能在t模式下使用
     52 #
     53 # # 0模式的使用的位置为参照的
     54 # 2:该模式代表指针移动的字节数是以文件末尾为参照的
     55 
     56 # 强调:0模式可以在t或者b中使用,1和2只能在b模式下使用
     57 
     58 # 0模式的使用
     59 # xxx5.txt文件内容是abc你好,abc各占一个字节,你好各占3个字节
     60 # with open('xxx5.txt','rt',encoding='utf-8') as f:
     61 #     f.seek(2,0)
     62 #     print(f.tell()) # 查看当前文件的指针距离开头位置的长度,输出结果为3
     63 #     print(f.read()) # 指针指向了c后面,则输出你好
     64 
     65 # t模式下会将读取的内容自动解码,所以必须保证读取的内容是一个完整的中文数据,否则解码失败
     66 
     67 # 1模式的使用
     68 with open('xxx6.txt', 'rb') as f:
     69     f.seek(3, 1)
     70     print(f.tell())
     71     print(f.read().decode('utf-8'))
     72     f.seek(3, 1)
     73     print(f.tell())
     74     print(f.read())
     75 
     76 # 2模式的使用
     77 with open('xxx7.txt', 'rb') as f:
     78     f.seek(0, 2)
     79     print(f.tell())
     80     f.seek(-3, 2)
     81     print(f.read().decode('utf-8'))
     82 
     83 # 实现动态查看最新一条日志的效果
     84 # 小练习:实现动态查看最新一条日志的效果
     85 # import time
     86 #
     87 # with open('access.log', mode='rb') as f:
     88 #     f.seek(0, 2)
     89 #     while True:
     90 #         line = f.readline()
     91 #         if len(line) == 0:
     92 #             # 没有内容
     93 #             time.sleep(0.5)
     94 #         else:
     95 #             print(line.decode('utf-8'), end='')
     96 
     97 # 文件的修改
     98 # 硬盘空间是无法修改的,硬盘中数据的更新都是用新内容覆盖旧内容
     99 # 内存中的数据是可以修改的
    100 with open('xxx8.txt', 'r+t', encoding='utf-8') as f:
    101     f.seek(9)
    102     f.write('<妇女主任>')
    103 
    104 # 文件对应的是硬盘空间,硬盘内容不能修改对应着文件内容也不可以修改,那我们看到的文件内容可以修改是怎么实现的呢?
    105 # 大致的思路是:将硬盘中文件内容读入内存,在内存中修改完毕后再覆盖会硬盘
    106 
    107 
    108 # 文件的修改方式1:
    109 # 实现思路:将文件内容一次性全部读入内存,然后在内存中修改完毕后再覆盖写回原文件
    110 # 缺点:一次性读入内存,会过多的占用内存
    111 # 优点:在文件修改过程中,同一份数据只有一份
    112 
    113 with open('xxx9.txt', 'rt', encoding='utf-8') as f:
    114     res = f.read()
    115 
    116 with open('xxx9.txt', 'wt', encoding='utf-8') as f:
    117     f.write(res.replace('egon', 'alex'))
    118 
    119 
    120 # 文件修改方式2:
    121 # 实现思路:以读的方式打开原文件,以写的方式打开一个临时文件,一行行读取原文件内容,修改完后写入临时文件,
    122 # 删掉原文件,将临时文件重命名为原文件
    123 # 缺点:在文件修改的过程中同一份数据存了两份
    124 # 优点:一行行读取原文件内容,不会占用太多的内存
    125 import os
    126 with open('db1.txt','rt',encoding='utf-8') as read_f,open('.db1.txt.temp','wt',encoding='utf-8') as write_f:
    127     for line in read_f:
    128         write_f.write(line.replace('egon','alex'))
    129 
    130 os.remove('db1.txt')
    131 os.rename('.db1.txt.temp','db1.txt')

     

posted @ 2024-11-04 10:59  lzp123456  阅读(2)  评论(0编辑  收藏  举报