Python ftplib上传带目录结构文件至FTP时文件落D盘根目录,如何创建服务端目录
上传文件全落到服务端根目录的核心原因
你的现有实现存在两个直接导致路径错乱的问题:
- 直接将本地文件的完整绝对路径拼接进
STOR指令,FTP服务端不会识别Windows本地盘符路径,会把这类带本地路径的字符串解析为服务端根目录下的无效路径,最终所有上传操作都会落到服务端默认的工作目录(也就是你提到的D盘根) - 代码本身存在语法错误:
"STOR " + filename", file)中filename后面多了一个未闭合的引号,字符串拼接逻辑本身就无法正常运行
带完整目录层级的上传实现方案
要实现连同子文件夹结构一起上传,不需要依赖第三方库,直接用FTPLIB原生能力就能完成,核心逻辑分三步:
- 先定位服务端的基础目标路径(对应你需求里的
D:/PatientRecords),逐层级校验目录是否存在,不存在就手动创建 - 遍历本地目录的所有子项时,把每个本地子文件夹换算成服务端对应的相对路径,逐层级创建缺失的目录结构,不要一次性传入完整多层路径给创建接口——大部分FTP服务端不支持递归创建不存在的多级目录
- 上传单个文件前,提前把FTP连接的工作目录切换到该文件对应的服务端层级,执行
STOR指令时只传文件名即可,不要拼接本地的绝对路径
可直接复用的核心代码
你当前使用的错误代码:
with open(filename, "rb") as file: ftp.storbinary("STOR " + filename", file)
替换后的可运行上传逻辑:
import os from ftplib import FTP def upload_full_dir(ftp_conn: FTP, local_root: str, remote_base_dir: str): # 初始化服务端基础目录 ftp_conn.cwd("/") remote_base_parts = remote_base_dir.strip("/").split("/") for layer in remote_base_parts: try: ftp_conn.cwd(layer) except: ftp_conn.mkd(layer) ftp_conn.cwd(layer) # 递归遍历本地目录 for current_local_root, sub_dirs, file_list in os.walk(local_root): # 计算当前本地目录对应的远程相对路径 current_relative_path = os.path.relpath(current_local_root, local_root).replace("\\", "/") # 处理远程子目录的创建与切换 if current_relative_path != ".": remote_layer_path = f"/{remote_base_dir.strip('/')}/{current_relative_path}" ftp_conn.cwd("/") for layer in remote_layer_path.strip("/").split("/"): try: ftp_conn.cwd(layer) except: ftp_conn.mkd(layer) ftp_conn.cwd(layer) # 上传当前目录下的所有文件 for single_file in file_list: local_file_path = os.path.join(current_local_root, single_file) with open(local_file_path, "rb") as upload_file: ftp_conn.storbinary(f"STOR {single_file}", upload_file)
容易踩的坑
- 禁止将本地Windows绝对路径拼入STOR指令:比如
STOR C:/PatientRecords/A/1.txt这类写法,服务端会直接把C:识别成根目录下的无效文件,最终所有文件都会落到默认工作目录 - 目录创建时必须做容错判断:已经存在的目录直接执行切换操作即可,不要强行调用创建接口,不然会直接抛服务端返回的“目录已存在”错误,中断整个上传流程
- 上传完成后记得及时关闭文件句柄,避免本地文件被长时间占用
内容的提问来源于stack exchange,提问作者qt.qt
相关产品推荐
相关产品推荐

