本篇博客为实现一键删除未引用包代码实现,使用python2.7实现,代码有点乱,不过大体思路就跟第一篇博客一样,使用python完全是为了练手,其中还有很多优化点,不过对于处理几千个文件的工程来说,搓搓有余,上个厕所回来就好了,话不多说 直接上代码
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import os.path
# 需要修改文件根目录
rootPath = 'H:\\nbgame\\nbgame_client_proj\NBGame\src\com\\nbgame'
# 1.建立一个等待处理as文件数组,将as文件视为普通文本文件,
asFileAry = []
def isDir(path):
'''是否是路径'''
return os.path.isdir(path)
def isAsFile(path):
'''是否是as文件'''
isAs = False
if os.path.isfile(path) == True and os.path.splitext(path)[1] == '.as':
isAs = True
return isAs
def checkDir(path):
'''筛选as文件路径核心方法,递归过程'''
if isDir(path) == False:
return
dirAry = os.listdir(path)
for x in xrange(0,len(dirAry)):
if isDir(path + '\\' + dirAry[x]) == True:
checkDir(path + '\\' + dirAry[x])
elif isAsFile(path + '\\' + dirAry[x]) == True:
asFileAry.append(path + '\\' + dirAry[x])
# (1)先筛选获取as文件列表,并保存在asFileAry列表中
checkDir(rootPath)
def getImportPkgName(fullName):
'''获取包名'''
nameAry = fullName.split('.')
pkgName = nameAry[len(nameAry) - 1]
if ';' in pkgName:
pkgName = pkgName[0:-1]
return pkgName
def isExistID(index,dic):
isExist = False
for x in xrange(0,len(dic.values())):
if index == int(dic.values()[x]):
isExist = True
break
return isExist
def delPkgByLine(path,delDic):
old_file = open(path,'r')
codeList = old_file.readlines()
newList = []
for x in xrange(0,len(codeList)):
if isExistID(x,delDic) == False:
newList.append(codeList[x])
new_file = open(path,'w')
new_file.truncate()
for str in newList:
new_file.writelines(str)
old_file.close()
new_file.close()
def handlerAsFile(path):
'''处理as文件'''
if isAsFile(path) == False:
return
# 1.打开as文件
asFile = open(path,'r')
# 2.逐行读取as文件并保存在数组中
codeList = asFile.readlines()
pkgDic = {}
pkgIndexDic = {}
# 3.遍历数组,如果是import关键字起头 列入包数组,并存储正文开始索引
for x in xrange(0,len(codeList)):
lineStr = codeList[x]
lineStr = lineStr.strip()
# 引用包
if lineStr[0:6] == "import":
pkgDic[getImportPkgName(lineStr)] = getImportPkgName(lineStr)
pkgIndexDic[getImportPkgName(lineStr)] = str(x)
else:
if len(pkgDic.keys()) > 0:
for i in range(0,len(pkgDic.keys())):
if pkgDic.keys()[i] in lineStr:
pkgDic[pkgDic.keys()[i]] = '1'
needDelDic = {}
for k in range(0,len(pkgDic.values())):
if pkgDic.values()[k] != '1':
key = pkgDic.values()[k]
index = pkgIndexDic.get(key)
needDelDic[key] = index
if len(needDelDic.keys()) > 0:
delPkgByLine(path = path,delDic = needDelDic)
asFile.close()
# (2)遍历as文件列表,逐个对as文件进行读写操作
for fileName in asFileAry:
print fileName
handlerAsFile(fileName)
以下对上面代码做一个分析:
1.首先通过调用checkDir方法,将根目录传进去,得到根目录下所有as文件路径,这一步没有什么难度,就是不断递归,如果文件后缀是.as就说明是as代码文件
2.遍历列表,处理as文件,这一步就是最为关键的一步,分几个小步来说
2.1读取as文件,将每行以字符串存到codeList中,遍历codeList,将每行的首尾祛除空格制表符,如果前6个字符是'import',就默认为引入包的代码段,否则就在之前存的包字典中去好是否存在引用,这里使用字典,主要考虑,字典自动去重,key值相同,value只会存在一个,算是偷了一个懒,如果存在引用将value设为‘1’,其实这里随便设个不可能的包名都是可以的,不过不能设置为‘*’,这个代码存在一个bug就是这个,bug我最后来讲
2.2遍历完成后,再去看包字典所有value是否都被设置成了‘1’,如果没有,就表示没有被引用,这个时候就需要调用delPkgByLine方法,之前为了方便,还存了一个字典,包名与对应行数的字典——pkgIndexDic,就是用于这个地方的
2.3python没有删除指定行的方法,只能重写文件,所有这里需要一个临时列表来存储每行代码,不过这里存在一个判断,就是之前存在需要删除的行不存储,筛选出来后就可以重写文件,这样一个文件未引用的包所在行代码就被删除了
这个方法不是最好的,但是至少是一个行得通的方式,实际测试了下3k文件,10多秒的样子就搞好了,其中还有不少可以优化点,等待你自己去思考吧,我就不深究了
最后,上面提到的bug,“*”在as中表示任何,引入包的时候也可以使用这个符号,一旦引入包的时候存在“*”包代码段的时候会出错,如果后面正文代码没有使用‘*’,这个本该引入的包会被删除。
最后的最后上一张我一键操作后的效果图吧,我真没想到平时写代码居然那么多代码有无用引用包代码段
一键删除未引入包系列,就最后还剩一个步骤了,就是发布应用程序版本了~