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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:24:24