文件操作

1 三问

1.1 什么是文件

文件是操作系统提供给用户或者应用程序的一种操作硬盘的机制/功能

1.2 为何要用文件

应用程序———–》遥控器
操作系统———–》文件
计算机硬件———-》硬盘

1.3 如何用文件

文件操作的基本流程:
1、应用程序打开文件,拿到一个文件对象/文件句柄
2、调用文件句柄下的读、写操作
3、关闭文件,回收操作系统资源

2 文件操作的基本流程

1
2
3
4
5
f = open('D:/python17期/day08/代码/aaa/a.txt',mode='rt',encoding="utf-8")  # windows默认:gbk
print(f)
res = f.read()
print(res)
f.close()

2.1 上下文管理

1
2
3
4
5
6
7
8
9
with open('aaa/a.txt',mode='rt',encoding="utf-8") as f,\
open(...) as f1,\
open(...) as f2:
f.read()
f1.read()
f2.read()

with open('aaa/a.txt',mode='rt',encoding="utf-8") as f:
print(f.read())

2.2 文件的mode

1
2
3
4
5
6
7
8
9
### 控制文件读写操作的模式
# r(默认的)
# w
# a


### 控制文件读写内容的模式
# t(默认的):无论读写都是以字符串为单位的,必须要指定encoding参数--->只能用于文件文件的处理
# b:无论读写都是以二进制位(bytes类型)单位的,一定不能指定encoding参数---》可以用于所有文件的处理
  • 1、r:只读模式,文件不存在则报错,文件存在文件指针则跳到文件开头

    1
    2
    with open('aaa/a.txt',mode='rt',encoding="utf-8") as f:
    print(f.read())
  • 2、w:只写模式,文件不存在则创建空文档文件指针处于文件开头,文件存在则清空文件指针处于文件开头

1
2
3
4
5
with open('aaa/a.txt',mode='wt',encoding="utf-8") as f:
f.write("你好\n")
f.write("哈哈哈\n")
f.write("我擦嘞\n")
f.write("撒打发士大夫")
  • 3、a:只追加写模式,文件不存在则创建空文档文件指针处于文件末尾,文件存在则指针处于文件末尾
    1
    2
    3
    4
    with open('aaa/a.txt',mode='at',encoding="utf-8") as f:
    f.write("你好1\n")
    f.write("你好2\n")
    f.write("你好3\n")
  • 4、b模式:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    with open('aaa/1.mp4',mode='rb') as f:
    res = f.read()
    print(res,type(res))
    for line in f:
    print(line)

    with open('aaa/a.txt',mode='rb') as f:
    res = f.read()
    # print(res,type(res))

    t = res.decode('utf-8')
    print(t)

    with open('aaa/a.txt',mode='wb') as f:
    f.write("你好".encode('utf-8'))

    with open('aaa/1.mp4',mode='rb') as src_f,open('D:/1111111.mp4',mode='wb') as dst_f:
    # dst_f.write(src_f.read())
    for line in src_f:
    dst_f.write(line)
    r+t
    w+t
    a+t

    2.3 file对象常用方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #1.判断文件是否可读或者可写,返回值为True或者False
    with open('a.txt',mode='rt',encoding='utf-8') as f:
    print(f.readable())
    print(f.writable())
    #2.f.readline() 读取一行内容,光标移动到第二行首部
    line = f.readline()
    print(line)
    #3.f.readlines() 读取每一行的内容,存放于列表中
    lines = f.readlines()
    print(lines)

    with open('a.txt',mode='wt',encoding='utf-8') as f:
    #4.f.writelines() 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换符。
    names = ["egon","tom","lili"]
    # for name in names:
    # f.write(name)
    f.writelines(names)
    f.write("1111\n222\n333\n")
    f.write('hello')
    f.writelines('hello')
    f.write("aaaaa")
    #5.f.flush() 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。
    f.flush()


    with open('a.txt',mode='at',encoding='utf-8') as f:
    f.truncate(6)
    #6.f.truncate()从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 windows 系统下的换行代表2个字符大小。

2.4 控制文件指针移动

2.4.1 控制文件内指针移动的单位

只有t模式下的read(n)代表的是字符个数,除此之外全都是字节个数
示例

1
2
3
4
5
6
7
8
9
# 控制文件内指针移动的单位: 只有t模式下的read(n)代表的是字符个数,除此之外全都是字节个数
with open('a.txt',mode='rt',encoding='utf-8') as f:
res = f.read(6)
print(res)

with open('a.txt',mode='rb') as f:
# res = f.read(6)
res = f.read(8)
print(res.decode('utf-8'))

2.4.2 主动控制文件指针移动的三种模式

  • 0模式: 参照文件开头移动n个字节

    1
    2
    f.seek(3,0)
    f.seek(6,0)
  • 1模式: 参照当前所在的位置移动n个字节

    1
    2
    f.seek(3,1)
    f.seek(6,1)
  • 2模式: 参照文件末尾置移动n个字节

    1
    2
    # f.seek(-3,2)
    # f.seek(-6,2)
  • ps: 只有0模式可以在t下使用,1和2模式都只能在b下使用*

2.4.3 实现 tail -f access.log

  • 日志写入
    1
    2
    3
    4
    import time

    with open('access.log', 'at', encoding='utf-8') as f:
    f.write('%s %s' % (time.strftime('%Y-%m-%d %H:%M:%S'), 'egon给lxxx转了一个亿'))
  • tail功能
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import time

    with open('Me/access.log', 'rb') as f:
    f.seek(0, 2)
    while True:
    data = f.readline()
    if len(data) == 0:
    time.sleep(0.3)
    else:
    print(data.decode('utf-8'), end='')

2.5 文件修改的两种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 修改文件的两种方式
# 方式一:
# 1、将文件内容一次性全部读入内存
# 2、在内存中将内容修改完毕
# 3、将新内容写回原文件
with open('Me/b.txt', mode='rt', encoding='utf-8') as f1:
data = f1.read()
res = data.replace("egon", 'EGON')

with open('Me/b.txt', mode='wt', encoding='utf-8') as f2:
f2.write(res)

# 方式二:
# 1、以读的方式打开源文件,以写的方式打开一个临时文件
# 2、从源文件中读出一行内容都内存中,修改完毕后再写入临时文件,循环往复直到读完原件
# 3、删除源文件,将临时文件改名为源文件名
import os

with open('Me/b.txt', mode='rt', encoding='utf-8') as src_f,
open('.b.txt.swp', mode='wt', encoding='utf-8') as dst_f:
for line in src_f:
dst_f.write(line.replace('EGON', 'egon'))

os.remove('Me/b.txt')
os.rename('.b.txt.swp', 'Me/b.txt')