本来是想在bypy基础上搞个自动传输系统,都准备最后收拢了,突然bypy就不能使用了。
还是果断放弃靠不住的这个软件了。因为将来终究这个软件是不能适应网络变化的。直接使用云盘同步功能,虽然百度会去掉文件最后修改时间的信息,但是可以先将信息放在文件名字上,下载后再写回来就可以了。这样也大大简化了系统,只要完成自动存档功能和及时运送文件到云同步区就可以了。
不过通过这个练习还是对python有了较扎实的认识。对程序设计也有了更透彻的理解认识。能够操控多个程序同时运行,用txt文件联系不同 的程序。认识到程序设计应先将大思路理清,将目标制定后,就深入研究各个环节所需要的概念和对应的实体,并根据不同的特性设计各个环节,例如为了对抗网络失败,让一个子程序不断去循环,就算子程序死掉还可以再激活,只要网络一通就会去完成任务。根据云文件难以把控的实际情况设计了镜像映射的方案,将复杂的文件树映射成序列以列表和txt文本进行传输。为了确保传递的安全性,建立了各种日志,以便查阅分析。总而言之,为了完成这个ZDCS系统,还是展开了很广泛深入的研究。对程序和人的对话沟通也有了认识。虽然最终将只保留一个简化版本,但是积累了相当多有价值的知识。
文件操作是其中的核心任务之一。之前没注意到正则表达式,对字符串的处理多走了点弯路。文件及文件夹的处理非常繁琐无聊,不过再回首也权当做了一次很深入的练习吧。
# -*- coding:utf-8 -*-
import os
import time
import shutil
# 01 判断是否为汉字,copy网友的
def ischin(uchar):
"""判断一个unicode是否是汉字"""
if uchar >= u'\u4e00' and uchar<=u'\u9fa5':
return True
else:
return False
##str.isalnum() #所有字符都是数字或者字母
##str.isalpha() #所有字符都是字母
##str.isdigit() #所有字符都是数字
##str.islower() #所有字符都是小写
##str.isupper() #所有字符都是大写
##str.istitle() #所有单词都是首字母大写
##str.isspace() #所有字符都是空白字符、\t、\n、\r
# 02 获取一个文件夹里的所有第一级子文件夹和文件
def DFfl(PATH):
XL = os.listdir(PATH )
XL.sort()
DLb = []
FLb = []
for patha in XL:
if os.path.splitext(patha)[1]=='':
DLb.append(patha)
else:
FLb.append(patha)
## print(XL)
##
## print(DLb)
##
## print(FLb)
return DLb ,FLb
# 03 建立一个文件夹 的镜像,并写入其最后一次修改时间和文件大小。
def JLjx(PAPH):
tuples = os.walk(PAPH)
for tuple1 in tuples:
## print(tuple1,'\n')
## print(tuple1[0],'\n')
## print(tuple1[1],'\n')
## print(tuple1[2],'\n')
patha = str(tuple1[0])
for name in tuple1[2]:
xx = os.stat(patha+'\\'+str(name))
wxx = xx.st_mtime
wxy = xx.st_size
## print(str(wxx))
filea = open(patha+'\\'+str(name)+'.txt','w',encoding="utf-8")
filea.write(str(wxx)+'\n'+str(wxy))
filea.close()
## print(tuple1[0],'\n')
## print(tuple1[1],'\n')
## print(tuple1[2],'\n')
for name in tuple1[2]:
os.remove(patha+'\\'+str(name))
# 04 输出一个文件夹所有各级文件夹和文件列表的 名字,虽不绝对,用于一般情况下的判定相等足矣
def MDFfl(PAPH):
'''
输出所有文件夹的名字列表和所有名字的列表
'''
tuples = os.walk(PAPH)
RQ = []
SQ = []
for tuple1 in tuples:
## print(tuple1[0],'\n')
##
## print(tuple1[1],'\n')
for iname in range(len(tuple1[1])):
RQ.append(tuple1[1][iname])
## print(tuple1[2],'\n')
for jname in range(len(tuple1[2])):
SQ.append(tuple1[2][jname])
## print(RQ)
## print(SQ)
return RQ, SQ
# 05 将一个文件夹里所有文件的后缀去掉
def SChz(PAPH):
tuples = os.walk(PAPH)
for tuple1 in tuples:
## print(tuple1,'\n')
## print(tuple1[0],'\n')
## print(tuple1[1],'\n')
## print(tuple1[2],'\n')
patha = str(tuple1[0])
for name in tuple1[2]:
sx=os.path.splitext(patha+'\\'+str(name))[0]#分离后缀
os.chdir(patha)
os.rename(str(name),str(sx))
# 06 输出一个文件夹所有的路径列表
def LJlb(PAPH):
tuples = os.walk(PAPH)
LJlb = []
for tuple1 in tuples:
## print(tuple1,'\n')
##
## print(tuple1[0],'\n')
LJlb.append(tuple1[0])
##
## print(tuple1[1],'\n')
##
## print(tuple1[2],'\n')
## print('*****************')
##
## print(LJlb)
return LJlb
# 07 由指定文件夹path获得最后名字为Y的所有路径
def LJmz(Y,PATH):
LBx = LJlb(PATH)
LBzf = []
xox = Y
for inchx in LBx:
if inchx.count(str(xox)) > 0 and inchx[(-len(str(xox))):-1]+inchx[-1] == str(xox) :
LBzf.append(inchx)
## print(LBzf)
##
## print(inchx)
else:
pass
#对LBzf按尖到根的顺序排列
Jhcn = set()
for kk in range(len(LBzf)):
ls = LBzf[kk].count(xox)
Jhcn.add(ls)
## print(Jhcn)
# 1) 获得最后名字为Y的路径含有Y的不同个数的指标集
Jhcn = list( Jhcn)
Jhcn.sort(reverse = True)
## print(Jhcn)
SLBzf = []
# 2) 把指标从最大到最小逐渐从原列表中抽出生成新的列表
for i in range(len(Jhcn)):
for xx in LBzf:
if xx.count(xox)== Jhcn[i] :
SLBzf.append(xx)
## print(SLBzf)
return SLBzf
##LJmz('新建文件夹','D:/ZDCS系统/短期备份区/测试')
# 08 将一个文件夹的全部文件的路径,最后修改时间,大小信息存储在文件和列表中
def WBwj(PAPH,TXTPATH):
tuples = os.walk(PAPH)
LJlb = []
for tuple1 in tuples:
## print(tuple1[2])
## print('xxxxxxxxxxxxxxxxxxxxxxxx')
patha = str(tuple1[0])
for name in tuple1[2]:
xx = os.stat(patha+'\\'+str(name))
## print(xx)
wxx = xx.st_mtime
## print(wxx)
wxy = xx.st_size
## print(wxy)
## LJlb.append(patha)
LJlb.append(patha+'\\'+str(name)+'$'+str(wxx)+'$'+str(wxy))#作为路径符号标准的是\\
## print(LJlb)
##
## print('0000000000')
LJlb.sort()
file = open(str(TXTPATH),'a+',encoding="utf-8")
for i in range(len(LJlb)):
file.write(str(LJlb[i])+'\n')
#记录文件的最后写入时间
aa = time.time()
file.write(str(aa))
file.close()
return LJlb
# 09 获得一个文件夹的全部文件及其路径
def WFwj(PAPH):
tuples = os.walk(PAPH)
LJa = []
LJb = []
LJc = []
for tuple1 in tuples:
patha = str(tuple1[0])
for name in tuple1[2]:
LJa.append(patha)#路径索引号与文件名的索引号一致
LJb.append(str(name))
LJc.append(patha+'\\'+str(name))
return LJa,LJb,LJc
# 10 由指定文件夹path获得文件名为Y的所有文件名及路径
def WFljm(Y,PATH):
LB = WFwj(PATH)
LBx =LB[1]#名字
LBy =LB[0]#路径
LBzf1 = []
LBzf2 = []
xox = Y
for i in range(len(LBx)):
ss = LBx[i]
if ss == str(xox) :
LBzf1.append(LBx[i])
LBzf2.append(LBy[i])
## print(LBzf)
##
## print(inchx)
else:
pass
return LBzf1,LBzf2#第一个是文件名,第二个是路径
##LJfz('AFFF图_t6.dwg','D:/ZDCS系统/短期备份区/测试/')
# 11 将文件夹里全部重名的文件夹和文件加上序号使之不重名且不改义
def CLcm(PATH):
# 1) 先获取重名的文件夹名字
PAPHb = PATH
AL = MDFfl(PAPHb)
## print(AL[0])
ChongD = set()
for xx in AL[0]:
if AL[0].count(xx)>1:
ChongD.add(xx)
ChongD = list(ChongD)
ChongD.sort()
## print(ChongD)
ChongDindex = []
for xx in ChongD:
## print(AL[0].count(xx))
## print(xx)
ChongDindex.append(AL[0].count(xx))
## print(ChongDindex)
#以上获取重名的文件夹名字和数量
# 2) 先要将CHongD中的路径进行排序,不能从根部改名字,不然上面的同名文件夹修改时就找不到路径了
#修改LJmz(y,PATH)函数,使它输出的路径按树尖到树根的顺序排列,先重命名树尖上的名字,就不会出现找不到路径的错误了
# 3) 对文件夹名字进行修改
for ix in range(len(ChongD)):
LBx = LJmz(ChongD[ix],PATH)
for jx in range(len(LBx)):
## print(LBx[jx])
## print(jx)
## os.getcwd()
## print(os.getcwd())
ts = str(LBx[jx])
CHf = ts.split("/")#用"/"能将'测试'前面的裂开,但后面的不能。用"\\"能裂开'测试'后面的。
#‘测试 ’就是我们操作对象所在的文件夹
ALb = CHf[-1].split("\\")
del CHf[-1]
CHf.extend(ALb)
del CHf[-1]
## print(LBx[jx])
CHg = ('/').join(CHf)
os.chdir(str(CHg))
## print(os.getcwd())
## print(ts)
os.rename(str(LBx[jx]),str(LBx[jx])+'('+str(jx)+')')
#4)对文件的操作是相当的
PAPHb = PATH
AL = MDFfl(PAPHb)
ChongD = set()
for xx in AL[1]:
if AL[1].count(xx)>1:
ChongD.add(xx)
ChongD = list(ChongD)
ChongD.sort()
ChongDindex = []
for xx in ChongD:
## print(AL[1].count(xx))
## print(xx)
ChongDindex.append(AL[1].count(xx))
## print('--------------------')
print(ChongD)
print(ChongDindex)
#以上获取重名的文件名字和数量
# 2) 文件不用考虑排序改名
# 3) 对重名文件名字进行修改
cmj = len(ChongD)
for ix in range(cmj):#不要为图方便将一些命令直接作用的函数表达放在循环结构中
LB = WFljm(ChongD[ix],PATH)
## print('2222222222222')
print(LB)
for jx in range(len(LB[0])):
## print(LB[0][jx])
## print(jx)
##
os.chdir(str(LB[1][jx]))
## print(os.getcwd())
os.rename(str(ChongD[ix]),'('+str(jx)+')'+str(ChongD[ix]))
##
##CLcm(PATHa)
# 12 获得一个文件夹的总字节数
def WJdx(PAPH):
tuples = os.walk(PAPH)
LJb = []
for tuple1 in tuples:
## print(tuple1,'\n')
## print(tuple1[0],'\n')
for xch in tuple1[2]:
fileinfo = os.stat(str(tuple1[0])+'/'+str(xch))
xcc = fileinfo.st_size
LJb.append(xcc)
num = 0
for xi in LJb:
num = xi+num
## print(num)
##
## print(tuple1[1],'\n')
##
## print(tuple1[2],'\n')
## print('*****************')
##
return num
# 13 将一个文件夹的内容移动到另一个文件夹
def ZJmv(pathx,pathy):
'''
直接将一个文件夹里面的内容移动到另一个文件夹
shutil.move主要是针对新建文件夹的,把一个文件夹里的内容复制到新建的文件夹
'''
Lb1 = DFfl(pathx)[0]
Lb2 = DFfl(pathx)[1]
for xi in Lb1:
shutil.move(pathx+'/'+str(xi),pathy+'/'+str(xi))
for xi in Lb2:
shutil.move(pathx+'/'+str(xi),pathy+'/'+str(xi))
##ZJmv('D:/ZDCS系统/工作区/测试','D:/ZDCS系统/人机对话区/新建文件夹')
# 14 将一个文件夹的内容复制到另一个文件夹
def ZJcp(pathx,pathy):
'''
直接将一个文件夹里面的内容复制到另一个文件夹
shutil.copy主要是针对新建文件夹的,把一个文件夹里的内容复制到新建的文件夹
'''
Lb1 = DFfl(pathx)[0]
Lb2 = DFfl(pathx)[1]
for xi in Lb1:
shutil.copytree(pathx+'/'+str(xi),pathy+'/'+str(xi))
for xi in Lb2:
shutil.copyfile(pathx+'/'+str(xi),pathy+'/'+str(xi))
##ZJcp('D:/ZDCS系统/工作区/测试','D:/ZDCS系统/人机对话区/新建文件夹')
#15 对一个文件夹中的文件按超过10天无修改进行存档
def CDwj(X):
pathm = X
# 1)找出需要存档的文件夹
CWJL = []
for wjj in MKwjcz.DFfl(X)[0]:
tuples = os.walk(str(X)+'/'+str(wjj))
LJb = []
ytime = time.time()
atime = time.localtime()
for tuple1 in tuples:
for xch in tuple1[2]:
fileinfo = os.stat(str(tuple1[0])+'/'+str(xch))
xcc = fileinfo.st_mtime
LJb.append(xcc)
LJb.sort()
if ytime - LJb[-1] > 10*24*3600:
CWJL.append(wjj)
print(CWJL) #查看所找到的文件夹是否正确
# 2)对找出的文件夹存档
for cwjj in CWJL:
none = False
for wjd in MKwjcz.DFfl('D:/ZDCS系统/存档区')[0]:
if wjd == cwjj:#找到与要存档文件夹名字同名的文件夹名字
none = True
else :
pass
if none:
print('同名')
#================================
nonea = False
#对这个同名文件夹的子文件夹序列(年度)进行分析
print(MKwjcz.DFfl('D:/ZDCS系统/存档区'+'/'+str(cwjj))[0])#如用wjd怎么会是2021?#因为wjd在改逻辑结构后并不在上面的for循环中顺序定义所以该wjd实际上变成别的值而非'同名a'
for wjjnian in MKwjcz.DFfl('D:/ZDCS系统/存档区'+'/'+str(cwjj))[0]:
print('wjjnian',wjjnian)
print('atime[0]',atime[0])
if str(atime[0]) == wjjnian :#要存档的文件夹所在的年与已有项目的年文件夹同
print(MKwjcz.DFfl('D:/ZDCS系统/存档区'+'/'+str(cwjj))[0])
nonea = True
print(wjjnian)
print(nonea)
if nonea:#'如果同年'
pass
#-----------------------------------------
print('同年')
noneb = False
#对这个同名的年文件夹的子文件夹(月度)进行分析
for wjjyue in MKwjcz.DFfl('D:/ZDCS系统/存档区'+'/'+str(cwjj)+'/'+str(wjjnian))[0]:
if wjjyue == str(atime[1]):#要存档的文件夹已有当月的文件夹
print('vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv')
print('同月项目的名称和月份')
print(str(cwjj))
print(str(wjjnian))
print(wjjyue)#虽然用过的名字wjjyue可以再使用并弃掉前者但在循环嵌套时会带来非常麻烦的错误难以查清
noneb = True
if noneb:
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
print('同月')
#要存档的工作区的这个文件夹是以项目名字命名的,存档要把它里面的子文件夹和文件放入该项目月文件夹
#但此时可能面临重名冲突,所以要先对该要存档文件夹进行不重名处理
print('D:/ZDCS系统/存档区'+'/'+str(cwjj)+'/'+str(wjjnian)+'/'+str(wjjyue))
print('D:/ZDCS系统/工作区/'+'xxx')
shutil.copytree('D:/ZDCS系统/存档区'+'/'+str(cwjj)+'/'+str(atime[0])+'/'+str(atime[1]),'D:/ZDCS系统/工作区/'+'xxx')#存档区该项目当月文件复制到这里
MKwjcz.CLcm('D:/ZDCS系统/工作区/')
shutil.rmtree('D:/ZDCS系统/工作区/'+'xxx')#删除辅助文件
#将含有str(cwjj)的那个文件夹的全部内容移动到存档区的该月文件夹
print('已运行到这里')
MKwjcz.ZJmv('D:/ZDCS系统/工作区/'+str(cwjj),'D:/ZDCS系统/存档区'+'/'+str(cwjj)+'/'+str(atime[0])+'/'+str(atime[1]))
os.chdir('D:/ZDCS系统/工作区')
os.rmdir(str(cwjj)) #直接删除就报错,使用了os.chdir('D:/ZDCS系统/工作区')就正常了
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
else:#新建月文件夹
shutil.move(str(pathm)+'/'+str(cwjj),'D:/ZDCS系统/存档区'+'/'+str(cwjj)+'/'+str(wjjnian)+'/'+str(atime[1]))
#-----------------------------------------------------------------------------
else:#新建年文件夹存档
shutil.move(str(pathm)+'/'+str(cwjj),'D:/ZDCS系统/存档区'+'/'+str(cwjj)+'/'+str(atime[0])+'/'+str(atime[1]))
#==============================================
else:#新建项目文件夹存档
shutil.move(str(pathm)+'/'+str(cwjj),'D:/ZDCS系统/存档区'+'/'+str(cwjj)+'/'+str(atime[0])+'/'+str(atime[1]))
print(CWJL)
return CWJL
# 16 将一个文件夹里的dwg文件按超过10天无修改转移到项目文件夹里
def WJJwj(X):
pathm = X
# 0) 只对工作区dwg格式的文件存档
DWG = []
for si in MKwjcz.DFfl(X)[1]:
if os.path.splitext(si)[-1] == '.dwg':#只对dwg格式的文件存档
DWG.append(si)
# 1)把文件的操作转换为文件夹的操作
CWJLy = [] #尽量不要共名
for wj in DWG:
ytime = time.time()
atime = time.localtime()
fileinfo = os.stat(str(pathm)+'/'+str(wj))
xcc = fileinfo.st_mtime
if ytime - xcc > 10*24*3600:
CWJLy.append(wj)
print('要存档的文件如下')
print(CWJLy) #查看所找到的文件是否正确
# 2)从文件名中获得项目名称,为文件创立相应的文件夹
pattern = r'[\s*]'
for xwj in CWJLy:
MingL = re.split(pattern,xwj)
XMing = MingL[0]
if os.path.splitext(XMing)[-1] == '':
print(XMing)
if os.path.exists(pathm+'/'+str(XMing)):
shutil.move(pathm+'/'+str(xwj),pathm+'/'+str(XMing)+'/'+str(xwj))
pass
else:
os.mkdir(pathm+'/'+str(XMing))
shutil.move(pathm+'/'+str(xwj),pathm+'/'+str(XMing)+'/'+str(xwj))
else:
os.mkdir(pathm+'/'+str(os.path.splitext(XMing)[0]))
shutil.move(pathm+'/'+str(xwj),pathm+'/'+str(os.path.splitext(XMing)[0]))
##patha = 'D:/ZDCS系统/工作区'
##
##WJJwj(patha)
##patha = 'D:/ZDCS系统/工作区'
##
##CDwj(patha)