PyThon用字典变量来提前加载各种文件到内存中去,避免程序频繁的访问外部文件,降低程序效率和可能出现不可预知的文件I/O错误

import copy  #支持对列表字典等类型支持深度COPY的库
#定义用字典储存各种文件二进制数据到内存中以方便快速使用的类class gc_MemFiles
class gc_MemFiles():
    #构造初始化函数:指定的文件生成内存文件,参数1:初始化的内存文件要传入的文件或文件列表(一个或多个文件)
    def __init__(self,fileNames,defFile):  
        self.dicMemFiles={} #将指定列表中的全部文件读入内存,并保存在此字典中,通过KEY来访问,默认为KEY=0时,留用给没有从字典中得到文件数据时的默认值
        self.lstMemFileName=[]  #对应字典读入的内存文件(文件应为绝对路径或模块可识别的路径不含路径的文件名),第0索引文件为默认文件留用,本变量仅用于调试用
        self.fileCount=0        #当前字典中文件的数量(含KEY=0的默认文件数量)
        self.MakeMemFile(fileNames,defFile,True)  #初始化时,第三个参数应为True
        
    #根据传入的文件名初始化内存文件(bNew=True时表示先清空原有的再重新创建,bNew=False时表是增加):本函数不允许传入的文件不能正确导入到内存文件中,因每个KEY对应其他代码的调用,如果KEY不一一对应,程序运行结果将不可预见
    #不论传入的文件不论是否创建成功,均会为内存字典分配一个KEY,只是对应的KEY的文件读入内存的二进制数据为None
    def MakeMemFile(self,fileNames,defFile='',bNew=False):
        if bNew:   #如果新建内存文件,会用defFile文件作为KEY=0的内存文件数据
            self.fileCount=0
            self.dicMemFiles.clear()
            self.lstMemFileName.clear()
            self.lstMemFileName.append(defFile)
            if(defFile==''):
                print('新建内存文件时,必须要指定一个默认文件为作字典的默认内存数据,现将字典KEY=0的默认值为None')
                self.dicMemFiles[0]=None
            self.fileCount=1    
            
        #处理参数表传入的默认文件名
        if(defFile==''):  #表示无需对默认文件进行任何操作
            pass
        else:  #如有定义默认文件名,则更新字典中的KEY=0的默认文件数据
            self.lstMemFileName[0]=defFile   #默认文件无论是否正确加载到内存文件中,列表中的值均为传入的内存文件名称
            if(os.path.exists(defFile)):
                with open(defFile, 'rb') as f:
                    binData = f.read()
                    self.dicMemFiles[0]=binData
                    print(f'当前默认文件数据对应的默认文件名="{defFile}"')
            else:
                print(f'指定默认文件"{defFile}"不存在,字典KEY=0的默认内存文件暂为None,请检查文件')
                self.dicMemFiles[0]=None

        #判断传入的fileNames是一列表文件组,还是单一的一个字符串文件
        vartype=type(fileNames)
        if(isinstance(fileNames,str)): #是单一字符串,即传入了一个单文件
            print(f'参数为字符串,即传入了一个单一文件"{fileNames}"')
            if(os.path.exists(fileNames)):
                with open(fileNames, 'rb') as f:
                    binData = f.read()
                    self.dicMemFiles[self.fileCount]=binData    
                    #f.close()
            else:
                print(f'指定文件"{fileNames}"不存在,向字典中增加一个内存文件出现错误!!,暂将此序号key={self.fileCount}文件同key=0的默认文件内容相同')
                self.dicMemFiles[self.fileCount]=self.dicMemFiles[0]  
            self.lstMemFileName.append(fileNames) 
            self.fileCount+=1    
        elif(isinstance(fileNames,list)): #是一列表变量,即传入了多个文件
            print(f'参数为列表,即传入了多个文件{fileNames}')
            for filename in fileNames:
                if(os.path.exists(filename)):
                    with open(filename, 'rb') as f:
                        rData = f.read()
                        self.dicMemFiles[self.fileCount]=rData      #内存文件增加一个        
                else:
                    print(f'指定文件"{filename}"不存在,向字典中增加一个内存文件出现错误!!,暂将此序号key={self.fileCount}文件同key=0的默认文件内容相同')
                    self.dicMemFiles[self.fileCount]=self.dicMemFiles[0]  
                self.lstMemFileName.append(filename) 
                self.fileCount+=1


    #得到内存文件中的二进制数据:参数1=要得到字典内存文件的KEY值,
    # bDeepCopy=True时,返回值时会用深度COPY一副本来使用,这样避免调用端对字典内存文件改动后影响其他同样在使用这个内存文件的
    # defData不为空时:如果没有从字典中得到相对应的,用defData作为返回值,为None时,以字典的key=0 的内容作为出错返回值
    def getMemFileData(self,dicKeyID,bDeepCopy=False,defData=None,bUseDicDefValue=True):
        data=None
        if(len(self.dicMemFiles)>0):
            if(defData==None):  #参数未再指定从字典中得到内存文件数据出错时的默认数据时,且bUseDicDefValue==Ture时得到字典中的KEY=0的默认值
                if(bUseDicDefValue):
                    data= self.dicMemFiles.get(dicKeyID, self.dicMemFiles[0]) #用get函数来得到对应字典key的值,如果调用函数defData值不为空,则用defData值,否则用g_lstMemFileName[0]作为默认值
                else:
                    data= self.dicMemFiles.get(dicKeyID, None)  #如没有正确得到字典中的值,返回None,而不是key=0的默认值
            else:
                data= self.dicMemFiles.get(dicKeyID, defData) #用get函数来得到对应字典key的值,如果调用函数defData值不为空,则用defData值,否则用g_lstMemFileName[0]作为默认值
            #如指定了defData的数据,但还是得到失败,且又指定了bUseDicDefValue=True,失败时采用KEY=0的默认数据时
            if(data==None and bUseDicDefValue):
                data= self.dicMemFiles.get(0,None)  #再次失败还是会得到一个None
            if(bDeepCopy):
                return copy.deepcopy(data)
        return data



用下面的代码来测试上面的类,下面中的部份或全部文件要同程序目录在一个目录中哦,下面所列文件不一定要全部准备齐,好了解文件不存在时的类代码的处理方式。

lstPath1=['1.png','2.png','3.png','100.png']
file1='200.png'
deffile='def.txt'
lstfile2=['300.png','2.png','1.png']
memfile=gc_MemFiles(lstPath1,deffile)
memfile.MakeMemFile(file1,'')
memfile.MakeMemFile(lstfile2,'')   
memfile.MakeMemFile(lstfile2,'def.txt',True)
data=memfile.getMemFileData(2)    
print(data) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mr_LuoWei2009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值