前几天写过一篇文章:python 从共享文件中自动拷贝指定文件到本地
今天把它完善一下,整个代码分为4块:测试代码脚本、命令行脚本、copy 功能脚本以及辅助工具脚本。
【备注:我是用的是python2.7,由于python3.x与2.x有很多地方不同,所以不要尝试在3.x上,以免出现未知错误】
首先是测试脚本:
在这里,由于是拷贝脚本的编写,必然涉及到源文件以及目标文件,那么先从源文件入手,想获得共享文件,首先得有一个共享文件所在服务器的ip地址,然后有一个已知源文件路径这样就有了srcFilename了,至于目标路径,随便设定。代码:
test.py:
import os , sys , Mycommand
def main():
hostIp = '192.168.0.111'
sharePath = '\\path'
filename = 'file_testname'
resultStr = []
resultStr.append([])
srcFilename = '\\\\' + hostIp + sharePath + '\\' + filename
desFilename = 'd:\\ftp\\ftp_download'
cmd = [
'C:\\python27\\python.exe',
'C:\\Users\\admin\\Desktop\\copy\\copyShareFile.py',
srcFilename,
desFilename
]
res = Mycommand.command(resultStr , cmd , 3)
if res == True:
print ('download success!')
else :
print ('download failed!')
if __name__ == '__main__':
main()
接下来是MyCommand模块,这个模块是使用subprocess.Popen创建命令行线程向copy那个自定义的脚本传参,这个模块为什么会有呢?为什么不使用copy直接拷贝呢?因为当考虑的时候,应该考虑共享文件不可访问或者路径不存在这种情况,那么如何识别不能顺利获取到想要的文件呢?开始的时候想用ping 命令判断是否可以访问到,但是实际做的时候发现,服务器那边可能将ping 功能关闭,这样当可以访问的时候,也会出现ping 不通的可能。后来想到,如果可以顺利找到共享文件那么就可以获得,之后使用os.path.exists()找的时候发现,如果找得到的时候,会瞬间找到,即使不能很快,至少3秒也应该能够找到了。但是如果不能找到,这个函数会阻塞,一直在那尝试找,直到达到了函数默认的timeout(大约是10秒以上)才会停止查找,但是我们不希望那样让它一直在那“傻傻的”找,而想自己定时,以至于我们可以根据具体情况设置一下界限,当限制时间内还没有找到共享文件那么就判断是不可访问,则立刻停止搜索,也就是将搜索所在的脚本kill掉(之前一直找如何控制函数运行时间,超时就kill,但是找到如何控制时间了,但是同一个线程中,感觉没办法kill一个函数,所以但提出来使用了这个方法),用户体验也就提升了,好了,贴代码:
Mycommand.py:
import sys , time , subprocess
class TimeoutError(Exception):
pass
def command(resultStr , cmd , timeout = 20):
print ('command start...')
process = subprocess.Popen(cmd , stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell = True)
beginTime = time.time()
secondsPass = 0
while True:
if process.poll() is not None:
break
secondsPass = time.time() - beginTime
if timeout and timeout < secondsPass:
process.terminate()
print ('running timeout!')
return False
#raise TimeoutError(cmd , timeout)
time.sleep(0.1)
if len(resultStr) > 0:
resultStr[0] = process.stdout.read()
return True
最后是比较常规的拷贝代码:
# -*- coding: cp936 -*-
import sys , os , re
def copyFileDir(srcFilename , desFilename):
status = False
try:
fileList = os.listdir(srcFilename)
for eachFile in fileList:
sourceF = os.path.join(srcFilename,eachFile)
targetF = os.path.join(desFilename,eachFile)
if os.path.isdir(sourceF):
if not os.path.exists(targetF):
os.makedir(targetF)
status = copyFileDir(sourceF,targetF)
else :
status = copyFile(sourceF,targetF)
except Exception,e:
print (e)
status = False
finally:
print ('copyFileDir function is quit!')
return status
def copyFile(srcFilename , desFilename):
status = False
copyCommand = 'copy %s %s'%(srcFilename,desFilename)
try:
if(os.popen(copyCommand)): #不用op.system(copyCommand),因为这个会弹出命令行界面
print ('copy done!')
status = True
else :
print ('copy failed!')
status = False
except Exception,e:
print (e)
status = False
finally:
print ('copyFile function is quit!')
return status
def copyFromSharePath(srcFilename,desFilename):
if not os.path.exists(srcFilename):
print ('no found '+srcFilename)
return False
if not os.path.exists(desFilename):
print ('no found '+desFilename)
os.makedirs(str(desFilename))
print ('create '+desFilename)
copyStatus = False
if os.path.isdir(srcFilename):
copyStatus = copyFileDir(srcFilename,desFilename)
else :
copyStatus = copyFile(srcFilename,desFilename)
return copyStatus
def main(argv = sys.argv):
if not len(argv) == 3:
print ('input parameters\'s count should be 3,not %s'%(len(argv)))
return
print ('脚本名字是:' + argv[0])
srcFilename = argv[1]
print ('源目录:' + argv[1])
desFilename = argv[2]
print ('目标目录:' + argv[2])
if os.path.isdir(srcFilename):
if os.path.isfile(desFilename):
print ('can not copy a folder to a file')
return
copyFromSharePath(srcFilename,desFilename)
if __name__=='__main__':
main()