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)