我在 python 中使用 pycurl 通过 ftp 传输文件。我可以使用以下方法在远程服务器上自动创建缺少的目录:
c.setopt(pycurl.FTP_CREATE_MISSING_DIRS, 1)
由于某些原因,我不得不切换到 ftplib。但我不知道如何在这里做同样的事情。是否有任何选项可以添加到 storbinary 函数中来做到这一点?或者我必须手动创建目录?
FTP_CREATE_MISSING_DIRS 是一个 curl 操作(在此处添加)。我冒昧地猜测您必须使用 ftplib 手动执行此操作,但我很想被证明是错误的,有人吗?
我会做类似以下的事情:(未经测试,需要捕捉ftplib.all_errors
)
ftp = ... # Create connection
# Change directories - create if it doesn't exist
def chdir(dir):
if directory_exists(dir) is False: # (or negate, whatever you prefer for readability)
ftp.mkd(dir)
ftp.cwd(dir)
# Check if directory exists (in current location)
def directory_exists(dir):
filelist = []
ftp.retrlines('LIST',filelist.append)
for f in filelist:
if f.split()[-1] == dir and f.upper().startswith('D'):
return True
return False
或者你可以这样做directory_exists
:(有点难以阅读?)
# Check if directory exists (in current location)
def directory_exists(dir):
filelist = []
ftp.retrlines('LIST',filelist.append)
return any(f.split()[-1] == dir and f.upper().startswith('D') for f in filelist)
我知道这是一篇旧帖子,但我只需要这个并想出了一个非常简单的功能。我是 Python 新手,所以我会很感激任何反馈。
from ftplib import FTP
ftp = FTP('domain.com', 'username', 'password')
def cdTree(currentDir):
if currentDir != "":
try:
ftp.cwd(currentDir)
except IOError:
cdTree("/".join(currentDir.split("/")[:-1]))
ftp.mkd(currentDir)
ftp.cwd(currentDir)
使用示例:
cdTree("/this/is/an/example")
我尝试将此作为评论添加到@Alex L 的答案中,但它太长了。如果要在途中创建目录,则需要在更改目录时递归下降。例如
def chdir(ftp, directory):
ch_dir_rec(ftp,directory.split('/'))
# Check if directory exists (in current location)
def directory_exists(ftp, directory):
filelist = []
ftp.retrlines('LIST',filelist.append)
for f in filelist:
if f.split()[-1] == directory and f.upper().startswith('D'):
return True
return False
def ch_dir_rec(ftp, descending_path_split):
if len(descending_path_split) == 0:
return
next_level_directory = descending_path_split.pop(0)
if not directory_exists(ftp,next_level_directory):
ftp.mkd(next_level_directory)
ftp.cwd(next_level_directory)
ch_dir_rec(ftp,descending_path_split)
另一种方法是简单地遍历每个路径元素,创建下一个并更改到新创建的目录。我的用例相当简单,因为我将项目从一个 FTP 服务器复制到另一个。
def create_ftp_path(session: ftplib.FTP, required_dir: str):
required_dir = required_dir.split('/')[:-1]
for path_item in required_dir:
if path_item.strip() == '':
continue
path_item = path_item.replace('/', '')
try:
session.cwd(path_item)
except:
session.mkd(path_item)
session.cwd(path_item)
注意事项:
required_dir
路径是来自该基本路径的路径。required_dir
包括文件名作为最后一个元素。/
字符,因为在我的情况下它们会导致553 permission denied
异常。此代码将在路径中创建所有丢失的文件夹:
...
def chdir(ftp_path, ftp_conn):
dirs = [d for d in ftp_path.split('/') if d != '']
for p in dirs:
print(p)
check_dir(p, ftp_conn)
def check_dir(dir, ftp_conn):
filelist = []
ftp_conn.retrlines('LIST', filelist.append)
found = False
for f in filelist:
if f.split()[-1] == dir and f.lower().startswith('d'):
found = True
if not found:
ftp_conn.mkd(dir)
ftp_conn.cwd(dir)
if __name__ == '__main__':
ftp_conn = ... # ftp connection
t = 'FTP/for_Vadim/1/2/3/'
chdir(t, ftp_conn)
此代码将检查路径中的所有目录并创建缺少的目录
在 "FTP/for_Vadim/" 之前 "FTP/for_Vadim/1/2/3/" 之后
我正在使用以下几行来解决 FTP 文件复制缺少的目录路径
import os
ftps = FTP_TLS('ftps_server')
ftps.connect()
ftps.login()
destination_dir_path = 'some/dir/path' # directory path on FTP
dir_path = ''
for i in destination_dir_path.split('/'):
dir_path = os.path.join(dir_path,i)
if i not in ftps.nlst(os.path.dirname(dir_path)):
ftps.mkd(dir_path) # create directory on the FTP
ftps.storbinary(...) # store file using the binary mode
我正在使用这样的东西(没有 cwd):
# -*- coding:utf-8 -*-
from ftplib import FTP, error_perm
def createDirs(ftp, dirpath):
"""
Create dir with subdirs.
:param ftp: connected FTP
:param dirpath: path (like 'test/test1/test2')
:type ftp: FTP
:type dirpath: str
:rtype: None
"""
dirpath = dirpath.replace('\\', '/')
tmp = dirpath.split('/')
dirs = []
for _ in tmp:
if len(dirs) == 0:
dirs.append(_)
continue
dirs.append(dirs[-1] + '/' + _)
for _ in dirs:
try:
ftp.mkd(_)
except error_perm as e:
e_str = str(e)
if '550' in e_str and 'File exists' in e_str:
continue
if __name__ == '__main__':
# init ftp
createDirs(ftp=ftp, dirpath='test/1/2/3')