文件操作

一、文件操作模式补充

除了r、w、a三种纯净模式外,还有r+、w+、a+三种模式,分别叫做读写、写读、追加写读

# mode='r+'
with open(r'test',mode='r+',encoding='utf-8') as f:
    print(f.readable())  # True
    print(f.writable())  # True


# mode='w+'
with open(r'test',mode='w+',encoding='utf-8') as f:
    print(f.readable())  # True
    print(f.writable())  # True


# mode='a+'
with open(r'test',mode='a+') as f:
    print(f.readable())  # True
    print(f.writable())  # True

二、文件内的光标操作

在将光标之前先了解read()函数中的参数,在rt模式下read内的数字表示的是字符的个数除此之外,数字标识的都是读取的字节数。

你追到我
我就让你嘿嘿嘿
test.text
# 在rt模式下 read内的数字 表示的是字符的个数
# 初次之外,数字表示的都是字节
# 一个中文需要三个字节
with open(r'test','r',encoding='utf-8') as f: print(f.read(5)) # 你追到我 with open(r'test','rb') as f: res1 = f.read(9) # 读的是九个字节bytes print(res1) # b'\xe4\xbd\xa0\xe8\xbf\xbd\xe5\x88\xb0' print(str(res1, encoding="utf-8")) # 你追到 with open(r'test','rb') as f: res2 = f.read(8) # 读的是八个字节bytes print(res2) # b'\xe4\xbd\xa0\xe8\xbf\xbd\xe5\x88' print(str(res2, encoding="utf-8")) # 报错:UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 6-7: unexpected end of data

文件内的光标的作用就是控制read()从哪开始读

光标的函数为seek(offset, whence)。offset指的是相对偏移量,即光标移动的位数;whence可以为0、1、2,0表示参照文件的开头,t和b都可以使用,1表示光标所在的当前位置,只能在b模式下使用,2表示参照文件的末尾,只能在b模式下使用。

你追到我
我就让你嘿嘿嘿
test.text
# whence = 0,rt模式下
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())  # 到我 我就让你嘿嘿嘿

# whence = 0,rb模式下
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(6,0)
    print(f.read(3).decode('utf-8'))  #

# whence = 1,rb模式下
with open(r'test','rb') as f:
    print(f.read(3).decode('utf-8'))  #
    f.seek(3,1)
    print(f.read(3).decode("utf-8"))  #

# whence = 2,rb模式下
with open(r'test','rb') as f:
    print(f.read())  # b'\xe4\xbd\xa0\xe8\xbf\xbd\xe5\x88\xb0\xe6\x88\x91\r\n\xe6\x88\x91\xe5\xb0\xb1\xe8\xae\xa9\xe4\xbd\xa0\xe5\x98\xbf\xe5\x98\xbf\xe5\x98\xbf'
    f.seek(-12,2)
    print(f.read())  # b'\xe4\xbd\xa0\xe5\x98\xbf\xe5\x98\xbf\xe5\x98\xbf'
    f.seek(-12, 2)
    print(f.read().decode('utf-8'))  # 你嘿嘿嘿
seek()

三、监测文件

基于文件的读写操作和光标的操作,可以写一个监测文件写入的程序,用来记录文件内容的添加记录。

2019-07-08 11:16:13 egon给jason发了1个亿的工资
2019-07-08 11:16:14 egon给jason发了1个亿的工资
2019-07-08 11:27:48 egon给jason发了1个亿的工资
2019-07-08 11:29:42 egon给jason发了1个亿的工资
2019-07-08 11:30:32 egon给jason发了1个亿的工资
2019-07-08 11:30:37 egon给jason发了1个亿的工资
2019-07-08 11:33:25 egon给jason发了1个亿的工资
2019-07-08 11:33:33 egon给jason发了1个亿的工资
2019-07-08 16:07:35 egon给jason发了1个亿的工资
test.text文件
import time
a = time.strftime("%Y-%m-%d %x")

with open(r"test01.text", mode="a", encoding="utf-8") as f:
    f.writer("%segon给我发了1亿工资“% a)  # 2019-07-08 16:07:35 egon给jason发了1个亿的工资
文件写入操作
# 文件监测
with open(r"test01.txt", mode="r",encoding="utf-8") as f:
    f.seek(0,2)  # 将文件光标移动到文件的末尾
    while True:  # 从文件的末尾循环读取文件末尾可能出现的数据
        a = f.readline()  # 读取可能被写入文件末尾的数据
        if a:  # 判断是否有数据写入
            print(a)  # 打印写入的数据
        
文件监测操作

四、截断文件

所谓的截断文件就是保留自己需要的内容,其余内容被删除

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

 

保留了test文件的前六个字节后的结果(右图)

         

五、修改文件

文件的存储有个特点,当一个文件存好后,若想向文件中插入字符间插入其它字符时,是不可行的,只能添加在文件的末尾。想要修改文件中的字符时,可以使用新字符替换掉原来的字符,或者将文件中的内容以字符串的形式读取出来,修改完成后存入另一个文件中,删除源文件,将新文件的名字改成源文件的名字。

# 修改文件
# 先将数据由硬盘读到内存(读文件)
# 在内存中完成修改(字符串的替换)
# 再覆盖原来的内容(写文件)
with open(r'test02.txt','r',encoding='utf-8') as f:
    data = f.read()
    print(data)
    print(type(data))

with open(r'test02.txt','w',encoding='utf-8') as f:
    res = data.replace('egon','jason')
    print(data)
    f.write(res)
方法一

# 文件修改方式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')
方法二

两种方法的优缺点:

对于方法一:

优点:任意时间硬盘上只有一个文件 不会占用过多硬盘空间
缺点:当文件过大的情况下,可能会造成内存溢出

对于方法二:

优点:内存中始终只有一行内容 不占内存
缺点:再某一时刻硬盘上会同时存在两个文件

 

posted on 2019-07-08 16:41  so_interesting  阅读(201)  评论(0编辑  收藏  举报

导航