使用OS.walk和paramiko将文件移动到ftp服务器导致EOFError?

时间:2014-06-10 13:22:46

标签: python-2.7 ftp paramiko os.walk

我的目标是遍历文件夹(和子文件夹)中的所有文件,检查文件是否已存在于ftp上。如果文件不存在,请输入目标文件夹,如果存在,则使用重命名归档旧文件并将新文件放在其中。到目前为止我的代码如下。

path = 'Z:\\_MAGENTO IMAGES\\2014\\Jun2014\\09Jun2014'
ssh = paramiko.SSHClient()  
log_file = 'C:\\Temp\\log.txt'
paramiko.util.log_to_file(log_file)    
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())



def upload_images():




    #' #In case the server's key is unknown,'
    #we will be adding it automatically to the list of known hosts 
    #ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))   

    #Loads the user's local known host file  
    ssh.connect('xxxxxxxxxxxxx', port=22,     username='xxxxxxxx', password='xxxxxxxxx') 
    ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command('ls /tmp') 
    print "output", ssh_stdout.read() #Reading output of the executed co'mmand 
error = ssh_stderr.read()  

    #Reading the error stream of the executed command
    print "err", error, len(error) 

    #Transfering files to and from the remote machine' 
    sftp = ssh.open_sftp()   
    #'sftp.get(remote_path, local_path)' 

    for root, dirs, files in os.walk(path):
        for fn in files:
            ftp_path = '/productimages/' + fn
            archive = '/productimages/archive/' + fn
            source = root + '\\' + fn
            try:
                sftp.stat(ftp_path)
            except IOError as e:
                print e.errno
                print errno.ENOENT
                if e.errno == errno.ENOENT:
                    print 'this is if'
                    sftp.put(source, ftp_path)

            else:
                print 'this is else'
                sftp.rename(ftp_path,archive)
                sftp.put(root + '\\' + fn, ftp_path)

            finally:
                sftp.close()
                ssh.close() 
            #update_log()  

会发生什么。如果文件不存在,我会得到一个EOFerror。如果文件已经存档,我将不得不为这种情况设置一些条件,但是当我到达时我会越过那个桥。我真的很厚,不能弄清楚问题。任何想法都赞赏。

1 个答案:

答案 0 :(得分:1)

EOFError因错误放置的finally子句而发生:sftpssh在首次处理的文件后关闭。

第二个问题是如果存在sftp.rename(ftp_path,archive)文件,archive将失败。

部分修复的upload_images()可能如下所示:

def upload_images():

    # some code skipped 

    def rexists(path):
        try:
            sftp.stat(path)
        except IOError as e:
            if e.errno == errno.ENOENT:
                return False
            raise
        return True

    try:
        for root, dirs, files in os.walk(path):
            for fn in files:
                print 'fn', fn
                ftp_path = '/nethome/auto.tester/tmp/productimages/' + fn
                archive = '/nethome/auto.tester/tmp/productimages/archive/' + fn
                source = root + '\\' + fn
                if not rexists(ftp_path):
                    sftp.put(source, ftp_path)
                else:
                    if rexists(archive):
                        sftp.remove(archive)
                    sftp.rename(ftp_path, archive)
                    sftp.put(root + '\\' + fn, ftp_path)

    finally:
        sftp.close()
        ssh.close()

但是如果path包含带文件的子目录,它仍然会失败。