NODE使用ftp和egg库读取ftp服务器上的文件并返回给前端,注意ftp库获取的stream是个Socket对象无法直接给ctx.body赋值返回数据,请给我完整代码流
时间: 2024-02-26 16:57:39 浏览: 128
好的,以下是完整的代码流程:
```javascript
const Ftp = require('ftp');
const fs = require('fs');
const path = require('path');
const sendToWormhole = require('stream-wormhole');
const awaitWriteStream = require('await-stream-ready').write;
const Controller = require('egg').Controller;
class FileController extends Controller {
async download() {
const { ctx } = this;
const client = new Ftp();
const filePath = ctx.query.filePath; // 文件在ftp服务器上的路径
const fileName = path.basename(filePath); // 文件名
const writeStream = fs.createWriteStream(fileName); // 创建本地文件写入流
// 连接ftp服务器
client.connect({
host: 'ftp.example.com',
user: 'username',
password: 'password',
});
client.on('ready', () => {
client.get(filePath, (err, stream) => {
if (err) {
client.end();
ctx.status = 500;
ctx.body = 'Failed to get file';
return;
}
// 使用stream-wormhole处理异常
stream.once('error', error => {
sendToWormhole(stream);
client.end();
ctx.status = 500;
ctx.body = 'Failed to get file';
});
// 将文件流pipe到本地写入流
stream.pipe(writeStream);
// 完成本地写入后,返回文件给前端
writeStream.on('finish', async () => {
const fileStream = fs.createReadStream(fileName);
// 使用await-stream-ready等待流完成
await awaitWriteStream(fileStream);
// 设置响应头,告诉浏览器返回的是文件流
ctx.set('Content-disposition', `attachment; filename=${fileName}`);
ctx.set('Content-Type', 'application/octet-stream');
ctx.body = fileStream;
// 关闭ftp连接
client.end();
});
});
});
client.on('error', error => {
ctx.status = 500;
ctx.body = 'Failed to connect ftp server';
});
}
}
module.exports = FileController;
```
在上面的代码中,我们首先连接ftp服务器,然后使用ftp库获取文件流。由于获取的流是一个Socket对象,我们无法直接将其赋值给ctx.body返回给前端,因此需要将其pipe到本地文件写入流中,等待写入完成后再将其返回给前端。在写入完成后,我们需要手动设置响应头告诉浏览器返回的是文件流,并关闭ftp连接。
阅读全文