文件操作

1.文件的概念

​ 文件就是操作系统给用户操作硬盘的快捷方式

​ 双击一个文件就是 从硬盘中加载数据到内存

​ 保存一个文件就是 把内存中的数据刷到硬盘中保存

2.文件的操作方式

​ 方式1:不常用 因为需要自己调用close()关闭文件

变量名 = open(’文件路径‘,’读写模式‘,’字符编码‘)

f = open('a.txt','r',encoding='utf8')
print(f.read())#读取该文件内容
f.close()#关闭该文件

​ 方式2:常用 不需要自己调用close()关闭文件方法

with open(r'文件路径','读写模式',encoding = 'utf8')as 变量名:

with open(r'a.txt','r',encoding='utf8')as f:
    print(f.read())#读取该文件内容

    
'''
注意:
	针对路径(字母与撬棍的组合可能会有特殊含义 在路径前面加r 可以取消特殊含义)
绝对路径:可以根据路径一步一步找到具体文件
相对路径:在当前所在的路径 下面去查找文件
'''

可以一次性打开多个文件:
with open (...)as f1,open(...)as f2:
    print(f1.read())
    print(f2.read())

3.文件的三种读写模式

image

1.只读模式:只能读不能写
with open(r'a.txt','r',encoding='utf8')as f:
    print(f.read())
   #文件存在时:正常读取内容
   #文件不存在:报错

2.只写模式:只能写不能读
with open(r'a.txt','w',encoding='utf8')as f:
    f.write('阿巴阿巴')
   #文件存在时:清空内容后写入数据
   #文件不存在:创建该文件
    
3.追加模式:文件末尾追加数据,不能读
with open(r'a.txt','a',encoding='utf8')as f:
    f.write('11111\n')  # \n可换行追加
   #文件存在时:在末尾追加新内容
   #文件不存在:创建该文件

'写入的数据可跟\n换行追加,但需注意在做文本比较时有个\n在影响判断'

4.文件的操作模式

1.t   文本模式
     文件操作的默认格式,r w a全称其实是rt wt at
       r = rt
       w = wt
       a = at
     1)只能操作'文本文件'
     2)需指定encoding参数,不写会用系统默认编码
     3)读写都是以'字符'为单位
        
2.b   二进制模式(bytes模式)#可以实现数据的拷贝
     需自己指定不能省略
       rb
       wb
       ab
     1)可以操作'所有类型'文件
     2)不用指定encoding参数(二进制不需要编码)
     3)读写都是以'bytes字节'为单位
    eg:
       with open(r'1.jpg','rb')as f:
            print(f.read())#打印读出来的数据就是二进制。用文本模式会报错!

5.文件的诸多方法

1.read() 
    一次性读取文件内容且光标会停留在文件末尾 继续读取则没内容
    1)'当文件数据较大且涉及多行时建议使用for循环'
      for i in f:
         print(i)
         #结果会把文件内容一行行显示出来(区别在于用完第一行会自动清除不占用内存)
    2)'read()括号内可以跟数字 在文本模式下表示读取几个字符'
      print(f.read(5))
      #结果会读取5个字符
    3)'括号内的数字 在二进制模式下表示读取几个字节'
       #一个英文1字节 一个中文3字节
2.readline() 
    一次只读一行内容,执行多次才可以读多行
3.readlines() 
    一次性读取文件内容 按照行数组成列表的形式#注意换行符
    #结果为:['aa\n', 'bb\n', 'cc']
4.readable() 
    判断文件是否具备读数据的能力#结果为布尔值
5.write() 
    写入数据#注意读写模式中是否是清除后填写
6.writeable() 
    判断文件是否具备写数据的能力#结果为布尔值
7.writelines() 
    接收一个列表 一次性将列表中所有数据写入
    f.writelines(['a\n','b\n'])
    #运行后该文件就会a和b各占一行。 注意换行符
8.flush() 
    将内存中文件数据立刻刷到硬盘中 类似于保存

6.文件的光标移动

seek(offset,whence)
    offset:控制光标移动的位移量  #字节为单位
    whence:移动的模式
            0是基于文件开头 #文本和二进制模式都可以使用
            1是基于光标当前位置 #只能二进制模式使用
            2是基于文件末尾 #只能二进制模式使用

文本模式练习:
	with open(r'a.txt','r',encoding='utf8')as f:
    print(f.read())  # 张三说要努力学习
    f.seek(6,0)      # 移动6个字节(2个中文字符),基于文件开头
    print(f.read())  # 说要努力学习

二进制模式练习:
	with open(r'a.txt','r',encoding='utf8')as f:
    print(f.read())  # 张三说要努力学习
    f.seek(6,0)      # 移动6个字节(2个中文字符),基于文件开头
    print(f.read())  # 说要努力学习
'如果第一个不注释掉 第二个则打印不出来 原因是当前光标已经在最后面 没有数据可读取'

    
    with open(r'a.txt','rb')as f:
    print(f.read().decode('utf8')) # 张三说要努力学习
    f.seek(-3,2) # 移动3个字节(1个中文字符),基于文件末尾
    print(f.read().decode('utf8')) # 习
'因为是在文件末尾,所以第一个参数用负数表示 则代表倒数第一个'
 
tell()可以获取当前光标移动了多少字节数
	with open(r'a.txt','rb')as f:
    print(f.read().decode('utf8'))#张三说要努力学习
    f.seek(-6,2)
    print(f.read(3).decode('utf8'))#学
    print(f.tell()) #21

7.文件内光标移动案例

#监控文件新增数据案例:

import time
with open(r'a.txt', 'rb') as f:
    f.seek(0, 2)#光标基于文件末尾移动0字节
    while True:
        line = f.readline()#一次性读取文件内容并按照行数组成列表形式
        if len(line) == 0:#判断文件内容长度如果=0
            time.sleep(0.5)#让程序睡眠0.5秒,目的是让cpu休息一下。否则会变成死循环一直在判断
        else:
            print(line.decode('utf8'), end='')#此时只要该文本文件中新增加了内容这里都会打印出来

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

1.硬盘修改数据:就是覆盖在原来的数据上

2.硬盘删除数据:从占有态改为自由态(看不到不代表不存在)。只有被覆盖了才算真正删除

9.文件内容修改

方式1:覆盖写

​ 先读取文件到内存 在内存中修改 然后w模式写入

with open(r'a.txt','r',encoding='utf8')as f:
    data = f.read()#将文本文件中的内容赋值给data
with open(r'a.txt','w',encoding='utf8')as f1:
    f1.write(data.replace('张三','李四'))#将文本中的张三换成李四然后写入在f1中
   """
   优点:是覆盖的模式去修改,硬盘只占用一块空间
   缺点:当数据较大时会造成内存溢出
   """

方式2:重命名

先读取文件内容到内存 在内存中完成修改 然后保存到另一个文件 再将源文件删除 将新文件命名成原文件的名字

#执行的速度太快其实就是删除文件后把第二个文件重命名
import os
with open(r'a.txt','r',encoding='utf8')as f1,open(r'aa.txt','w',encoding='utf8')as f2:
   for i in f1:
       f2.write(i.replace('张三', '李四'))
os.remove('a.txt')  # 删除文件
os.rename('aa.txt', 'a.txt')  # 重命名文件
  """
  优点:不会造成内存溢出
  缺点:可能临时需要占用硬盘两个地方的空间
  """