使用ssh2-sftp-client从Buffer上传文件时如何指定文件名?
解决ssh2-sftp-client从Buffer上传文件并指定文件名的问题
我之前也碰到过类似的情况,你的代码里其实藏着两个关键问题:一是远程路径没有指定具体文件名,二是对put方法的参数使用可能有点误解。咱们一步步来解决:
问题分析
你当前的put调用里,第二个参数是/var/www/bucket——这看起来是个目录路径,而不是具体的文件路径。当你上传Buffer时,ssh2-sftp-client需要明确知道要把这个Buffer存成什么文件,只给目录的话它没法自动生成文件名,这就是上传失败的核心原因。
解决方案
1. 明确指定远程文件路径(包含文件名)
你可以从Multer的req.file对象里获取原文件名(req.file.originalname),或者自定义一个文件名,把它拼到远程目录后面,形成完整的文件路径。比如:
const remoteFilePath = `/var/www/bucket/${req.file.originalname}`;
2. 调整put方法的调用
put方法的第二个参数必须是完整的远程文件路径,第三个参数如果是布尔值的话,控制的是是否启用压缩(useCompression),更清晰的方式是传入配置对象,明确参数含义。
下面是修正后的完整代码:
const sftp = new require('ssh2-sftp-client')(); sftp.connect({ host: 'some.IP.address.here', port: 22, // 建议用数字类型,字符串也能工作但更规范的是数字 username: 'username', password: 'password' }) .then(() => { // 拼接完整的远程文件路径,包含文件名 const remoteFilePath = `/var/www/bucket/${req.file.originalname}`; // 上传Buffer到指定的远程文件 return sftp.put(req.file.buffer, remoteFilePath, { flags: 'w', // 写入模式,默认就是w,可省略,但明确写出来更清晰 encoding: null // 因为是Buffer,所以编码设为null }); }) .then(() => { console.log('文件上传成功!'); return sftp.end(); // 记得关闭连接 }) .catch((err) => { console.error('上传出错:', err); // 出错后也要确保连接关闭 sftp.end().catch(e => console.error('关闭连接出错:', e)); });
额外注意事项
- 目录存在性检查:如果不确定
/var/www/bucket目录是否存在,可以在上传前先检查并创建:const remoteDir = '/var/www/bucket'; const exists = await sftp.exists(remoteDir); if (!exists) { await sftp.mkdir(remoteDir, true); // true表示递归创建父目录 } - 自定义文件名:如果不想用原文件名,也可以自己生成,比如用时间戳+后缀:
const fileExt = req.file.originalname.split('.').pop(); const customFileName = `upload-${Date.now()}.${fileExt}`; const remoteFilePath = `/var/www/bucket/${customFileName}`;
内容的提问来源于stack exchange,提问作者Petr Fila
相关产品推荐
相关产品推荐

