Node.js从SFTP下载.txt.pgp文件失败的技术求助
SFTP下载.txt.pgp文件失败的排查与解决
兄弟,我之前踩过几乎一模一样的SFTP下载坑——能拿到文件列表但死活下不了文件,结合你用的几个npm包,给你捋捋问题所在和解决办法:
先排查最容易忽略的核心问题
- 本地权限与路径:先确认本地目标文件夹有没有写入权限(比如你用root跑Node但目标文件夹是普通用户权限,或者反过来);另外一定要用绝对路径保存文件,相对路径很容易写到你没注意的地方(比如项目根目录之外)。
- 远程路径正确性:你用
readdir/list拿到的可能是相对路径,下载时一定要拼上远程服务器的根目录(比如远程文件夹是/data/files,不能只写test.txt.pgp,要写/data/files/test.txt.pgp)。
针对你用的几个包的正确实现
1. ssh2 包的正确fastGet写法
很多人栽在异步操作未完成就关闭连接上,给你补全完整可运行的代码:
const Client = require('ssh2').Client; const fs = require('fs'); const path = require('path'); const conn = new Client(); conn.on('ready', () => { console.log('Client :: ready'); conn.sftp((err, sftp) => { if (err) throw err; // 务必用远程绝对路径 const remoteFilePath = '/remote/server/path/your-file.txt.pgp'; // 用path.resolve生成本地绝对路径,确保文件夹存在 const localFilePath = path.resolve(__dirname, './downloads/your-file.txt.pgp'); fs.mkdirSync(path.dirname(localFilePath), { recursive: true }); // fastGet的回调里再关闭连接,确保下载完成 sftp.fastGet(remoteFilePath, localFilePath, (err) => { if (err) { console.error('下载失败:', err.message); } else { console.log('文件成功保存到:', localFilePath); } conn.end(); // 必须等下载完成再关连接 }); }); }).connect({ host: '你的SFTP服务器地址', port: 22, username: '你的用户名', password: '你的密码' // 或者用privateKey: fs.readFileSync('./your-key.pem') });
重点提示:如果提前调用
conn.end(),进程会直接终止,下载操作还没完成就被打断,本地自然没有文件。
2. ssh2-sftp-client 包的正确写法
这个包用Promise封装更友好,一定要用await等待异步操作完成:
const SftpClient = require('ssh2-sftp-client'); const path = require('path'); async function downloadPGPFile() { const sftp = new SftpClient(); try { await sftp.connect({ host: '你的SFTP服务器地址', port: 22, username: '你的用户名', password: '你的密码' }); console.log('SFTP连接成功'); const remotePath = '/remote/server/path/your-file.txt.pgp'; const localPath = path.resolve(__dirname, './downloads/your-file.txt.pgp'); // 先创建本地文件夹(如果不存在) await sftp.mkdir(path.dirname(localPath), { recursive: true }); // 用get方法或者fastGet都可以 await sftp.get(remotePath, localPath); console.log('下载完成,文件路径:', localPath); } catch (err) { console.error('下载出错:', err.message); } finally { // 无论成功失败都要关闭连接 await sftp.end(); } } // 调用异步函数 downloadPGPFile();
坑点:如果不用
await,函数会直接执行完毕,进程退出,下载操作根本没机会执行。
3. node-ssh 包的实现
node-ssh的SFTP下载同样要注意异步等待:
const NodeSSH = require('node-ssh'); const path = require('path'); const ssh = new NodeSSH(); async function fetchPGPFile() { try { await ssh.connect({ host: '你的SFTP服务器地址', username: '你的用户名', password: '你的密码' }); const remotePath = '/remote/server/path/your-file.txt.pgp'; const localPath = path.resolve(__dirname, './downloads/your-file.txt.pgp'); // 用sftpFastGet提升下载速度 await ssh.sftpFastGet(remotePath, localPath); console.log('文件下载成功'); } catch (err) { console.error('操作失败:', err.message); } finally { ssh.dispose(); // 释放连接 } } fetchPGPFile();
额外排查技巧
- 开启debug日志:在连接配置里加
debug: console.log,能看到SFTP的交互细节,比如服务器是否返回错误、文件是否存在:// 以ssh2为例 conn.connect({ // 其他配置 debug: (msg) => console.log('SFTP Debug:', msg) }); - 检查文件状态:用
sftp.stat(remotePath)获取远程文件的大小、权限等信息,下载后对比本地文件大小,如果本地是0字节,大概率是连接提前关闭或者权限问题。
内容的提问来源于stack exchange,提问作者Viet
相关产品推荐
相关产品推荐

