You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python从SFTP文件夹删除文件时遇异常求助

问题排查:SFTP删除文件时报"Bad message"错误

核心问题

已实现远程文件下载到本地、再上传至同级备份文件夹的流程,但执行sftp.remove(file_path)时触发如下错误:

Error reading file test_abs_2022135201552.pslog: Bad message
get和put功能正常,需求为单个文件处理完成后立即删除,而非批量操作。

排查与解决方向

1. 检查文件路径的正确性

代码片段存在明显逻辑遗漏:

  • 执行remote_files = sftp.listdir(station_folder_path)后,缺少遍历remote_files的循环(即for file in remote_files:),直接使用file变量会导致未定义错误。
  • file_path必须是远程服务器的完整路径,需用os.path.join(station_folder_path, file)拼接,仅传文件名会导致SFTP找不到目标文件。

2. 排查文件权限或锁定状态

  • 部分SFTP服务器在文件传输完成后会短暂锁定文件,导致立即删除失败,可尝试在remove前添加短暂延迟(如time.sleep(1)),但更稳妥的方式是确认服务器端是否存在文件锁定机制。
  • 验证SFTP用户对原文件所在目录是否拥有删除权限,部分服务器仅开放读取权限,也会返回模糊的"Bad message"错误。

3. 验证Paramiko版本与服务器兼容性

  • 旧版本Paramiko可能与特定SFTP服务器(如特定版本OpenSSH、商用SFTP服务)存在兼容性问题,建议升级至最新稳定版:
    pip install --upgrade paramiko
    
  • 先用原生SFTP命令行测试删除操作:
    sftp user@your-sftp-host
    rm /path/to/your/file.pslog
    
    若命令行可正常删除,问题大概率出在Paramiko代码或版本;若命令行也报错,则是服务器端问题(权限、文件状态等)。

4. 修正代码逻辑中的错误

补全循环、修正变量名与路径拼接后的示例代码:

source_path = "/project/"
local_path = r'C:\Users\Desktop\project'

df_staging = pd.DataFrame()
    
def main():
    transport = paramiko.Transport((sftp_host, sftp_port))
    transport.connect(username=sftp_username, password=sftp_password)
    sftp = paramiko.SFTPClient.from_transport(transport)

    global df_staging

    try:
        main_folders = sftp.listdir(source_path) 

        for main_folder in main_folders:
            main_folder_path = os.path.join(source_path, main_folder)  # 修正变量名
            station_folders = sftp.listdir(main_folder_path) 

            # 创建远程备份文件夹
            backup_folder_path = os.path.join(main_folder_path, 'backup')
            if 'backup' not in sftp.listdir(main_folder_path):
                sftp.mkdir(backup_folder_path)
                print("Backup folder created")
                
            # 创建本地文件夹(用exists替代listdir判断更可靠)
            local_main_folder = os.path.join(local_path, main_folder)
            if not os.path.exists(local_main_folder):
                os.mkdir(local_main_folder)

            for station_folder in station_folders:
                if station_folder != 'backup':
                    station_folder_path = os.path.join(main_folder_path, station_folder) 
                    remote_files = sftp.listdir(station_folder_path) 

                    # 补全遍历文件的循环
                    for file in remote_files:
                        file_path = os.path.join(station_folder_path, file)  # 拼接完整远程路径
                        local_file_path = os.path.join(local_main_folder, file)
                        remote_backup_path = os.path.join(backup_folder_path, file)
                        
                        try:
                            # 下载文件
                            sftp.get(file_path, local_file_path)
                            # 上传到备份文件夹
                            sftp.put(local_file_path, remote_backup_path)
                            # 删除原文件
                            sftp.remove(file_path)
                            print(f"Done transferring and deleting: {file} ")
                        except Exception as e:
                            print(f"Error processing file {file}: {str(e)}")
                        finally:
                            # 可选:清理本地临时文件
                            if os.path.exists(local_file_path):
                                os.remove(local_file_path)
    except Exception as e:
        print(f"Main process error: {str(e)}")
    finally:
        # 确保连接关闭
        sftp.close()
        transport.close()

内容的提问来源于stack exchange,提问作者Jolin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:59:56