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

如何通过SFTP传输需身份认证的Windows网络共享路径下的文件

实现方案

核心思路

你无需先将共享文件下载到本地临时目录,可直接通过SMB协议完成Windows共享目录的身份认证,读取文件流后直接传给SFTP客户端完成上传,减少不必要的IO开销。

实现步骤

1. 引入SMB客户端依赖

推荐使用jcifs-ng,它是JCIFS的活跃维护分支,支持SMB2/SMB3协议,兼容性比旧版JCIFS更好。Maven依赖如下:

<dependency>
    <groupId>eu.agno3.jcifs</groupId>
    <artifactId>jcifs-ng</artifactId>
    <version>2.1.10</version>
</dependency>

2. 完整实现代码

直接读取SMB共享文件流,复用你原有SFTP逻辑完成上传,示例如下:

import jcifs.CIFSContext;
import jcifs.Configuration;
import jcifs.config.PropertyConfiguration;
import jcifs.context.BaseContext;
import jcifs.smb.NtlmPasswordAuthenticator;
import jcifs.smb.SmbFile;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;

import java.io.InputStream;
import java.util.Properties;

public class SmbToSftp {
    public static void main(String[] args) {
        // SMB共享配置
        String smbFileUrl = "smb://100.xx.24.55/SFTPData/file.txt";
        String smbUsername = "你的共享用户名";
        // 如果是域账号,格式为 域名\\用户名,比如 "DOMAIN\\admin"
        String smbPassword = "你的共享密码";

        // SFTP配置
        String sftpHost = "100.XX.XX.XX";
        String sftpUsername = "username";
        String sftpPassword = "password";
        String sftpTargetPath = "/home/user/test/file.txt";

        try {
            // 初始化SMB上下文
            Properties prop = new Properties();
            // 开启SMB2/SMB3支持
            prop.setProperty("jcifs.smb.client.enableSMB2", "true");
            Configuration config = new PropertyConfiguration(prop);
            CIFSContext baseContext = new BaseContext(config);
            CIFSContext authContext = baseContext.withCredentials(
                    new NtlmPasswordAuthenticator("", smbUsername, smbPassword)
            );

            // 读取SMB共享文件流,try-with-resources自动释放资源
            try (SmbFile smbFile = new SmbFile(smbFileUrl, authContext);
                 InputStream smbInputStream = smbFile.getInputStream();
                 SSHClient ssh = new SSHClient()) {

                // 原有SFTP连接逻辑
                ssh.addHostKeyVerifier(new PromiscuousVerifier());
                ssh.connect(sftpHost);
                ssh.authPassword(sftpUsername, sftpPassword);

                try (SFTPClient sftp = ssh.newSFTPClient()) {
                    // 直接将SMB文件流上传到SFTP,无需落盘
                    sftp.put(smbInputStream, sftpTargetPath);
                }
                ssh.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 自定义异常处理逻辑
        }
    }
}

补充说明

  • 如果你的Java程序运行在Windows系统上,也可以先将共享目录映射为网络驱动器,直接用原有File类读取文件,但该方案依赖服务器的映射配置,可移植性差,不推荐生产环境使用
  • 示例中使用了try-with-resources语法自动关闭流、SSH连接、SFTP客户端,避免资源泄漏,你原有代码可以参考调整
  • 若共享文件较大,可调整SFTP的缓冲区大小提升传输效率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:15:03