如何通过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
相关产品推荐
相关产品推荐

