day08-文件处理2

目录

  • 文件内光标的移动

  • 文件修改

 

一、文件内光标移动

1.1 使用read(3):

#1. 文件打开方式为文本模式时,代表读取3个字符

#2. 文件打开方式为b模式时,代表读取3个字节

1.2 其余的文件内光标移动都是以字节为单位如seek,tell,truncate

# 1.游标操作的是字节,所有只能在b模式下进行操作
# 2.游标操作可以改变操作位置,r模式下可以改变位置进行操作,所有主模式选择r模式
# 3.seek(offset, whence):
# -- offset:相对偏移量, 光标移动的位数为整数就是往后偏移多少个字节,负数就是往前偏移多少个字节
# -- whence:
0:参照文件的开头 t和b都可以使用
1:参照光标所在的当前位置 只能在b模式下用
2:参照文件的末尾 只能在b模式下使用

1.2.1 注意:

#1. seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的

#2. truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果

1.3 具体操作

# 你真是帅呆了
with open('target.txt', 'rb') as f:
# 先读6个字节
data = f.read(6)
print(data.decode('utf-8')) # 你是
# 将游标从头开始往后偏移3个字节
f.seek(3, 0)
data = f.read(6)
print(data.decode('utf-8')) # 是日
# 从当前游标位置往前偏移3个字节
f.seek(-3, 1)
data = f.read(3)
print(data.decode('utf-8')) #

f.seek(-3, 2)
data = f.read(3)
print(data.decode('utf-8')) #



# 在rt模式下 read内的数字 表示的是字符的个数
# 初次之外,数字表示的都是字节
# with open(r'test','r',encoding='utf-8') as f:
# print(f.read(5))

# with open(r'test','rb') as f:
# res = f.read(10) # 读的是三个字节bytes
# print(res)
# print(res.decode('utf-8'))


# 文件内光标的移动
"""
f.seek(offset,whence)
offset:相对偏移量 光标移动的位数
whence:
0:参照文件的开头 t和b都可以使用
1:参照光标所在的当前位置 只能在b模式下用
2:参照文件的末尾 只能在b模式下使用
"""
# with open(r'test','rt',encoding='utf-8') as f:
# print(f.read(1))
# # f.seek(6,0) # seek移动都是字节数
# # f.seek(4,0) # seek移动都是字节数
# # print(f.read(1))
# f.seek(0,0)
# print(f.read(1))
# f.seek(0, 0)
# print(f.read(1))
# f.seek(6,0)
# print(f.read())

 

# with open(r'test','rb') as f:
# print(f.read(3).decode('utf-8'))
# f.seek(0,0)
# print(f.read(3).decode('utf-8'))
# f.seek(7,0)
# print(f.read(1).decode('utf-8'))
# # f.seek(6,0) # seek移动都是字节数
# # f.seek(4,0) # seek移动都是字节数

# with open(r'test','rb') as f:
# print(f.read(3).decode('utf-8'))
# f.seek(3,1)
# print(f.read(1))
# f.seek(6,0) # seek移动都是字节数
# f.seek(4,0) # seek移动都是字节数


# with open(r'test','rb') as f:
# print(f.read())
# f.seek(-4,2)
# print(f.read().decode('utf-8'))

# with open(r'test','r+',encoding='utf-8') as f:
# f.seek(3,0)
# f.write('过')

1.4 练习:基于seek实现tail -f功能

import time
with open('test.txt','rb') as f:
    f.seek(0,2)
    while True:
        line=f.readline()
        if line:
            print(line.decode('utf-8'))
        else:
            time.sleep(0.2)
View Code

1.5 写日志

import time

res = time.strftime('%Y-%m-%d %X')
# print(res,type(res))
#
with open(r'test.txt', 'a', encoding='utf-8') as f:
    f.write('%s egon给jason发了1个亿的工资\n' % res)

1.6 检测文件内容

with open(r'test01.txt','rb') as f:
    # 先将光标移动到文件末尾
    f.seek(0,2)
    while True:
        res = f.readline()
        # 查看光标移动了多少位 bytes
        # print(f.tell())
        if res:
            print("新增的文件内容:%s"%res.decode('utf-8'))
            # 说明有人操作当前文件
        # else:
        #     # 说明文件没有被任何人操作
        #     print('暂无其他人操作该文件')

 1.7 截断文件

with open(r'test','a',encoding='utf-8') as f:
    f.truncate(6)  # 接收的字节的长度 整型
    # 保留0~6字节数 后面的全部删除(截断)

 

 二、文件的修改

#文件的数据是存放于硬盘上的,因而只存在覆盖、不存在修改这么一说,我们平时看到的修改文件,都是模拟出来的效果,具体的说有两种实现方式:

方式一:将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)

# 问题:修改文件

# 思路:
# 将数据从硬盘读入到内存(读文件)
# 在内存中修改数据 (字符串的转换)
# 将修改好的数据存到硬盘,覆盖之前的文件 (写文件)

# 转化为代码
with open(r"test02.txt", 'r', encoding='utf-8') as l:
    data = l.read()

with open(r"test02.txt", 'w', encoding='utf-8') as l:
    res = data.replace('jason', 'egon')
    l.write(res)
import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    data=read_f.read() #全部读入内存,如果文件很大,会很卡
    data=data.replace('alex','SB') #在内存中完成修改

    write_f.write(data) #一次性写入新文件

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 

方式二:将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件

# 文件修改方式2
# 创建一个新文件
# 循环读取老文件内容到内存进行修改  将修改好的内容写到新文件中
# 将老文件删除  将新文件的名字改成老文件名
import os

with open(r'test02.txt','r',encoding='utf-8') as read_f,\
        open(r'test02.swap','a',encoding='utf-8') as write_f:
    for line in read_f:
        new_line = line.replace('jason','egon')
        write_f.write(new_line)
os.remove('test02.txt')
os.rename('test02.swap','test02.txt')
import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    for line in read_f:
        line=line.replace('alex','SB')
        write_f.write(line)

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 

练习题:

 
 
1. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数,求出本次购物花费的总钱数
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3

2. 修改文件内容,把文件中的alex都替换成SB
posted @ 2019-07-08 21:12  辕子  阅读(123)  评论(0编辑  收藏  举报