1、通用文件copy工具实现
1)第一种方法
src_file = input('请输入源文件的路径:').strip()
dst_file = input('请输入目标文件的路径:').strip()
with open(r'{}'.format(src_file),'rb') as f1,
open(r'{}'.format(dst_file),'wb') as f2:
content = f1.read()
f2.write(content)
此方法一次性将源文件存储的所有数据加载到内存中,内存外泄风险极大,一旦发生内存外泄,需要开辟硬盘作为虚拟内存,严重拖慢计算机的运行速度。
2)第二种方法
src_file = input('请输入源文件路径:').strip()
dst_file = input('请输入目标文件路径:').strip()
with open(r'{}'.format(src_file),'rb') as f1,
open(r'{}'.format(dst_file),'wb') as f2:
for line in f1:
f2.write(line)
此方法将源文件内容一行行加载到内存中复制给另外一个文件,如果源文件每一行的内容适量,则相安无事;但不排除有的行会出现非常非常多的内容,那样同样对内存造成威胁。
3)第三种方法
src_file = input('请输入源文件路径:').strip()
dst_file = input('请输入目标文件路径:').strip()
with open(r'{}'.format(src_file),'rb') as f1,
open(r'{}'.format(dst_file),'wb') as f2:
while True:
content = f1.read(1024) #指定每次循环读入内存的内容为1024bytes
if len(content) == 0:
break
f2.write(content)
此方法指定每次读入内存的数据为1024字节,不会对内存造成威胁。
2、基于seek控制指针移动,测试r+、w+、a+模式下的读写内容
1)r+模式
a.txt的内容为:abcdefg你好我好大家好
with open(r'a.txt','r+b') as f:
print(f.tell()) #指针位于开始位置,打印0
f.seek(7,1) #指针向后移动7,指针位于7的位置
content = f.read().decode('utf-8') #读取指针7后面的内容并进行转码
print(content) #(abcdefg|你好我好大家好) 打印指针位置7后面的内容: 你好我好大家好
print(f.tell()) #28 此时指针处于末尾
f.seek(-21,2) #指针相对于末尾向前移动21个字节,回到位置7
print(f.tell()) #7
f.write('他好我也好'.encode('utf-8')) #从当前指针位置7开始写入'他好我也好',指针向后移动15个字节
print(f.tell()) #22
f.seek(-15,1) #指针相对于当前位置22向前移动了15个字节,回到位置7
print(f.tell()) #7
print(f.read().decode('utf-8')) #'他好我也好’覆盖了'你好我好大',输出'他好我也好家好'
print(f.tell()) #28
2)w+模式
a.txt的内容为:abcdefg你好我好大家好
with open(r'a.txt','w+b') as f:
print(f.tell()) #输出0,清空文件内容,指针位于文件开头。
f.write('abcdefg你好我好大家好'.encode('utf-8')) #文件中写入内容
print(f.tell()) #输出28;指针位于文件末尾
f.seek(-21,2) #指针移动到相对于文件末尾为21的位置,即移动到文件指针为7的位置
print(f.tell()) #输出7
f.seek(-7,1) #指针相对于当前位置向前移动7个字节,移动到文件开头,指针位置为0
print(f.tell()) #输出0
print(f.read(10).decode('utf-8')) #读入前10个字节的内容,输出: abcdefg你
print(f.tell()) #输出10
3)a+模式
a.txt的内容为:abcdefg你好我好大家好
with open(r'a.txt','a+b') as f:
print(f.tell()) #指针位于文件末尾,输出为28
f.seek(-12,2) #指针移动到文件末尾前12字节处,位置为16,
print(f.tell()) #输出16
f.seek(-9,1) #指针相当于当前位置向前移动9个字节,位置为7
print(f.tell()) #输出7
f.write('大家好才是真的好'.encode('utf-8')) #在末尾追加写入'大家好才是真的好',指针移动到末尾52
f.flush() #将写入缓冲区的内容flush一下
print(f.tell()) #输出52 不进行flushe则输出31,只是指针位置显示不对而已,实际上已经在末尾了
f.seek(-24,1) #相对于当前位置(末尾)向前移动24个字节,指针位置为28
print(f.tell()) #输出28
print(f.read().decode('utf-8')) #输出'大家好才是真的好',指针移动到末尾52
print(f.tell()) #输出52
3、tail -f access.log程序实现
1)监测自己输入的内容
with open(r'access.log','a+b') as f:
while True:
content = input('输入一段内容:').strip()
f.write(content.encode('utf-8'))
num = len(content.encode('utf-8'))
f.seek(-num,2)
print(f.read().decode('utf-8'))
2)监测别的用户访问
import time
with open(r'access.log','rb') as f:
f.seek(0,2) #将指针移动到文件末尾
while True:
content = f.readline()
if len(content) == 0:
time.sleep(0.5)
else:
print(content.decode('utf-8'),end='')