[Python]-10-文件读写(下)

CodeRiftMaster
• 阅读 1457

引言

这篇文章介绍如何使用python的os与shutil模块,对文件或文件夹进行读写、创建、删除等操作。

文章目录

0×3.实例:日志文件轮换
0×4.内存文件读写

0×3.实例:日志文件轮换

有时候我们可能需要不断的写入一些日志,每次写入的时候,会产生一个新的版本,新版本永远是不带文件号的,然后老版本会被复制成带尾号的样子,例如:qingsword.log,qingsword.log.1,qingsword.log.2,不带数字的是最新版本,2为最旧的版本,再次写入时2版本会被复制成3版本,1版本复制成2,最近一次保存会被复制成1,但是每次这样手动操作太麻烦了,如果文件量巨大耗时耗力,那么如何让程序自动来完成这些数字的轮换呢,请看下面这个实例:

#!/usr/bin/env python
#coding=utf-8
import os
import shutil
import time

#------
def make_version_path(path,version):
    """返回版本文件路径"""
    if version==0:
        return path
    else:
        return path+"."+str(version)
#------
def rotate(path,version=0):
    """完成文件轮换"""
    if version>4:
        return
    old_path=make_version_path(path,version)
    if not os.path.exists(old_path):
        raise OSError("'%s' doesn't exist."%old_path)
    new_path=make_version_path(path,version+1)
    if os.path.exists(new_path):
        rotate(path, version+1)
    shutil.copy(old_path,new_path)
#------
def rotate_log_file(path):
    """创建新日志文件"""
    if os.path.exists(path):
        with open(path,"a") as file1:
            file1.write("\n"+time.ctime(time.time()))
    else:
        with open(path,"w") as file1:
            file1.write(time.ctime(time.time()))
    rotate(path)

rotate_log_file("/home/qing/test/qingsword/qingsword.log")

#运行程序后,"/home/qing/test/qingsword/"下会创建一个"qingsword.log"文件,反复运行这个程序,会发现目录中的文件数量最多为6个,最大的文件编号为"qingsword.log.5",这是因为在rotate()方法中做了最大版本号限制,如果version高于4,那么就结束调用自身,这段程最后可以完成文件版本从,4>5,3>4,2>3,1>2,0>1的版本复制操作。

0×4.内存文件读写

有时我们不需要将数据写入硬盘,只需要在内存中创建一个临时文件流,暂时保存一些数据,这个时候就可以用到StringIO和BytesIO,前者用来读写字符串数据,后者用来读写二进制数据,请看下面的实例:

#!/usr/bin/env python3
#coding=utf-8
#导入内存读写模块
from io import StringIO,BytesIO

#初始化一个空内存字符串读写对象
with StringIO() as si:
    #同文件读写一样,写入数据
    si.write("""My website:
www.qingsword.com""")
    #查看当前文件流指针位置,写入后指针在文件流的末尾
    print(si.tell())  #29
    #将指针指向第一个字符
    si.seek(0)
    #读取全部内容(如果没有使用seek(0),这一步将读取不到任何数据)
    print(si.read())

    #读取完成后,指针停留在文件流末尾
    print(si.tell()) #29
    #将指针移动到第三个字符的位置开始读取
    si.seek(2)
    L=si.readlines()
    for line in L:
        print(line.strip())
    #如果不移动数据流指针,想一次性读取所有数据流,可以使用getvalue()方法
    print(si.getvalue())

#程序输出
29
My website:
www.qingsword.com
29
website:
www.qingsword.com
My website:
www.qingsword.com


#初始化一个二进制内存数据流对象,将晴刃这两个字编码成utf-8,写入这个数据流对象
with BytesIO() as bf:
    bf.write("晴刃".encode("utf-8"))
    print(bf.getvalue())
    bf.seek(0)
    print(bf.read(3))
    print(bf.tell())

#程序输出
b'\xe6\x99\xb4\xe5\x88\x83'
b'\xe6\x99\xb4'
3

必要时,我们可以将内存中的文件流写入磁盘中的指定文件中,例如:

#!/usr/bin/env python3
#coding=utf-8
from io import StringIO
#创建一个内存文件流,并传入两行字符串,同时打开一个可写的磁盘文件流
with StringIO("晴刃\nwww.qingsword.com") as mf,\
     open("qing","w") as f1:
    mf.seek(0) #将内存文件流指针设置成0

    #读取内存文件流中的所有数据,写入磁盘中当前脚本所在目录下的qing文件中
    f1.write(mf.read())

#查看写入是否成功
with open("qing","r") as f1:
    print(f1.read())

#程序输出(输出换行了,因为内存流创建的时候,包含了一个换行符\n)
晴刃
www.qingsword.com
点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
4年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Stella981 Stella981
4年前
Scapy 从入门到放弃
0x00前言最近闲的没事,抽空了解下地表最强的嗅探和收发包的工具:scapy。scapy是一个python模块,使用简单,并且能灵活地构造各种数据包,是进行网络安全审计的好帮手。0x01安装因为2020年python官方便不再支持python2,所以使用python3安装。!(https://oscimg.oschina.net/os
Wesley13 Wesley13
4年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
4年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
4年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
4年前
JavaWeb 调用接口
JavaWeb 如何调用接口CreateTime2018年4月2日19:04:29Author:Marydon1.所需jar包!(https://oscimg.oschina.net/oscnet/0f139
Stella981 Stella981
4年前
Linux日志安全分析技巧
0x00前言我正在整理一个项目,收集和汇总了一些应急响应案例(不断更新中)。GitHub地址:https://github.com/Bypass007/EmergencyResponseNotes本文主要介绍Linux日志分析的技巧,更多详细信息请访问Github地址,欢迎Star。0x01日志简介Lin