python文件处理

2021-06-07 06:03

阅读:595

标签:复制   prism   本质   读写   for   when   sdn   span   boolean   

一、什么是文件处理?
我们知道,程序运行的时候,产生的数据都是存储在内存当中的,但是内存不是永久保存,一旦断电,数据就会消失,要想永久保存数据,我们就需要将数据保存到硬盘,而操作计算机硬件是操作系统干的活儿。所以操作系统为用户和应用程序提供了调用机制,取名为文件。文件本质上就是调用操作系统,从而控制计算机硬件。

二、如何使用文件
1、文件操作的三个流程

  • 应用程序向操作系统发起系统调用open(),操作系统打开该文件,对应一块硬盘空间,并返回一个文件对象赋值给一个变量f,也叫作文件句柄
f =  open("aaa.txt",mode="rt",encoding="utf-8")
  • 应用程序通过调用文件下的文件对象(文件句柄),通过操作系统对文件进行读/写操作
f = open("aaa.txt",mode="rt",encoding="utf-8")
f.read()
  • 关闭文件,回收操作系统资源;python中,垃圾回收机制会在文件关闭后回收变量f
f = open("aaa.txt",mode="rt",encoding="utf-8")
f.read()
f.close()

2、上下文管理
什么是上下文管理?我们需要知道操作系统能够打开的文件个是有限,所以在我们打开文件进行相应操作后,务必关闭文件,回收操作系统资源,这就是上下文管理。
但是有的童鞋总会忘了关闭文件,浪费宝贵的资源,所以python提供了with关键字来帮我们管理上下文

# 打开一个文件
with open("xxx.txt","rt",encoding="gbk") as f:
    print(f.read())
# 2、可用用with同时打开多个文件,用逗号分隔开即可
with open(‘a.txt‘,‘r‘) as read_f,open(‘b.txt‘,‘w‘) as write_f:  
    data = read_f.read()
    write_f.write(data)

这里with关键字的作用就是在文件操作完毕后,自动关闭文件,回收操作系统资源,傻瓜好用

3、文件的mode
open函数()的完整参数如下:
open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
参数说明:

  • file: 必需,文件路径(相对或者绝对路径)
  • mode: 可选,文件打开模式
  • buffering: 设置缓冲
  • encoding:一般使用utf8
  • errors: 报错级别
  • newline: 区分换行符
  • closefd: 传入的file参数类型
  • opener:
    一般来说,我们只需要传入file、mode、encoding三个参数,file不用多讲,接下来详细讲解mode的多种模式
    技术图片
    技术图片
    需要注意,r、w、a模式可以单独使用,此时默认采用t模式,但是t、b模式不能单独使用

下面通过具体的代码演示:

# r模式
with open("bbb.txt",mode="rt",encoding="utf-8") as f:
    res = f.read()
    print(res)

# w模式
with open("xxx.txt","wt",encoding="utf-8") as f_1: # 这里是清除了原文件进行写入
    f_1.write("111\n")
    f_1.write("222\n")
    f_1.write("333\n")

# a模式
with open("xxx.txt",mode="at",encoding="utf-8") as f_2: # 这里是在原文件后面进行追加写入
    f_2.write("aaa\n")
    f_2.write("bbb\n")
    f_2.write("ccc\n")

t模式与b模式
大前提: tb模式均不能单独使用,必须与r/w/a之一结合使用
t(默认的):文本模式
1. 读写文件都是以字符串为单位的
2. 只能针对文本文件
3. 必须指定encoding参数
b:二进制模式:
1.读写文件都是以bytes/二进制为单位的
2. 可以针对所有文件
3. 一定不能指定encoding参数

# t模式
with open("bbb.txt",mode="rt",encoding="utf-8") as f:
    res = f.read()
    print(res)

# b模式
with open("xxx.txt",mode="rb") as f_1:
    res = f_1.read()
    print(res) # b‘111\r\n222\r\n333\r\naaa\r\nbbb\r\nccc\r\n\xd5\xc5\r\n‘

小练习:文件复制程序,可以实现任意文件的复制

# 文件复制小程序
txt_copy = input("请输入需要复制的文件路径>>>")
with open(txt_copy,mode="rb") as f_1,     open("copy.txt",mode="wb") as f_2:
    for line in f_1:
        f_2.write(line)

4、文件常用操作

  • f.read 读取所有的内容,光标移到文件的末尾
  • f.readline 读取一行内容,光标移动到第二行首部
  • f.readlines 读取每一行内容,存放于列表中
# f.read() #读取所有内容,光标移动到文件末尾
with open(‘access.log.txt‘,"rt",encoding="utf-8") as f:
    res = f.read()
    print(res)
# f.readline() #读取一行内容,光标移动到第二行首部
with open(‘access.log.txt‘, "rt", encoding="utf-8") as f:
    line = f.readline()
    print(line)
# f.readlines() #读取每一行内容,存放于列表中
with open(‘access.log.txt‘, "rt", encoding="utf-8") as f:
    line = f.readlines()
    print(line)
  • f.write(‘1111\n222\n’) #针对文本模式的写,需要自己写换行符
  • f.write(‘1111\n222\n’.encode(‘utf-8’)) #针对b模式的写,需要自己写换行符
  • f.writelines([‘333\n’,‘444\n’]) #文件模式,将列表里的元素遍历添加进文件
  • f.writelines([bytes(‘333\n’,encoding=‘utf-8’),‘444\n’.encode(‘utf-8’)]) #b模式可用,将列表里的 元素遍历写入文件
# f.write(‘1111\n222\n‘) #针对文本模式的写,需要自己写换行符
with open(‘access.log.txt‘, "at",encoding="utf-8") as f:
    f.write("hhhhh\nheiheihie\n")
# f.write(‘1111\n222\n‘.encode(‘utf-8‘)) #针对b模式的写,需要自己写换行符
with open(‘access.log.txt‘, "ab") as f:
    f.write("hhhh\n".encode("utf-8"))
# f.writelines([‘333\n‘,‘444\n‘]) #文件模式
with open(‘access.log.txt‘, "at",encoding="utf-8") as f:
    f.writelines(["aaaaa\n","bbbbb\n"])
# f.writelines([bytes(‘333\n‘,encoding=‘utf-8‘),‘444\n‘.encode(‘utf-8‘)]) #b模式
with open(‘access.log.txt‘, "ab") as f:
    f.writelines([bytes(‘333\n‘, encoding=‘utf-8‘), ‘444\n‘.encode(‘utf-8‘)])
  • f.readable() #文件是否可读
  • f.writable() #文件是否可读
  • f.closed #文件是否关闭
  • f.encoding #如果文件打开模式为b,则没有该属性
  • f.flush() #立刻将文件内容从内存刷到硬盘
  • f.name

5、文件指针操作
我们在使用open函数打开文件后,是可以控制文件的指针移动的,可以读取到我们想要的数值

1)read(n)
在r模式下,可以使用read(n)方法实现读取指定内容,但是需要注意:

  • 只有在t模式下read(n)代表从当前指针位置向后读取n个字符
  • b模式下read(n)代表从当前指针文职向后移动n个字节
# 读取六个字符
with open("access.log.txt","rt",encoding="utf-8") as f:
    x = f.read(6)
    print(x)
# 读取多个字节
with open("access.log.txt","rb") as f:
    y = f.read(6)
    print(y.decode("utf-8"))
# 注意由于我们使用的是utf-8的编码格式,所以在b模式下使用read()方法时,英文字符占一个字节
# 中文字符占三个字节,需要注意取的字节数,否则会无法解析出中文字符

2)f.seek(n,whence)方法
可以指定参数,控制指针在文件中移动,模式如下:

  • 0模式,参照文件开头移动n个字节
  • 1模式,参照当前位置移动n个字节
  • 2模式,参照文件末尾位置移动n个字节,此时n一般使用负数
  • 注意:只有0模式可以在t模式下使用,1,2模式只能在b模式下使用
with open("access.log.txt","rb") as f:
    f.seek(3,0) #参照文件开头移动3个字节
    f.seek(4,1) # 参照当前位置向后移动4个字节,由于是r模式,所以参照开头
    f.seek(-4,2) # 参照文件末尾往前移动4个字节

6、案例实操
1)实现将指针移到文件末尾的方法

  • 使用a模式
  • 使用f.seek()的2模式
    2)日志追踪:设计程序自动向acces.log.txt文件追加日志记录,tail程序判断是否有追加新的日志,有就打出,无就等待0.3s
""""
自动生成日志记录
导入random、time模块,模拟随机生成的日志记录
"""

import time
import random

while True:
    x = random.random() # 随机生成一个数,用作模拟用户产生记录的时间差
    with open("access.log.txt","at",encoding="utf-8") as f:
        y = "今天吃了{}个苹果".format(x)
        f.write("%s %s\n" %(time.strftime(‘%Y-%m-%d %H:%M:%S‘),y))
        time.sleep(x)
"""
监控文件末尾
如果有新日志产生则打印
如果没有就等待0.3秒
"""

import time

with open("access.log.txt","rb") as f:
    f.seek(0,2)

    while True:
        line = f.readline()
        if len(line) == 0:
            time.sleep(0.3)
        else:
            print(line.decode("utf-8"),end="")

7、修改文件的两种方式
1)方式一:

  • 将整个文件读到内存;
  • 在内存中修改文件
  • 修改完毕后再把文件写回文件
# 方式一
with open("access.log.txt","rt",encoding="utf-8") as f1:
    x = f1.read()

    with open("access.log.txt","wt",encoding="utf-8") as f2:
        f2.write(x.replace("水果","香蕉"))

方式二:

  • 以读的方式打开文件,以写的模式打开一个临时文件;
  • 从源文件读取一行,修改后写入临时文件,如此循环,知道读完源文件
  • 最后删除源文件,将临时文件改名成源文件
# 方式二
import os

with open("access.log.txt","rt",encoding="utf-8") as f1,    open(".access.log.txt.swp","wt",encoding="utf-8") as f2:
    for i in f1:
        f2.write(i.replace("香蕉","苹果"))

os.remove("access.log.txt")
os.rename(".access.log.txt.swp","access.log.txt")

python文件处理

标签:复制   prism   本质   读写   for   when   sdn   span   boolean   

原文地址:https://www.cnblogs.com/zhangchengchao123/p/14588763.html


评论


亲,登录后才可以留言!