如何让强大的不保存到nodejs和express应用程序上的var/文件夹



我正在使用强大的功能来解析传入文件并将其存储在AWS S3 上

当我调试代码时,我发现最可怕的是首先将其保存到/var/folders/的磁盘上,随着时间的推移,一些不必要的文件堆积在磁盘上,这可能会导致以后出现大问题。

我在没有完全理解的情况下使用代码,现在又使用,这真是太愚蠢了

我必须弄清楚如何在将解析后的文件保存到S3后将其删除,或者在不将其存储在磁盘中的情况下将其保存到S3。但问题是我该怎么做?

如果有人能给我指明正确的方向,我将不胜感激

这就是我处理文件的方式:

import formidable, { Files, Fields } from 'formidable';
const form = new formidable.IncomingForm();
form.parse(req, async (err: any, fields: Fields, files: Files) => {
let uploadUrl = await util
.uploadToS3({
file: files.uploadFile,
pathName: 'myPathName/inS3',
fileKeyName: 'file',
})
.catch((err) => console.log('S3 error =>', err));
}

我想我找到了。根据文档,请参阅options.fileWriteStreamHandler,"您需要有一个函数,该函数将返回一个可写流的实例,该实例将接收上载的文件数据。使用此选项,您可以对上传的文件数据进行流式传输的位置进行任何自定义行为。如果你想将上传的文件写入其他类型的云存储(AWS S3、Azure blob存储、谷歌云存储(或私人文件存储,这是你想要的选项定义此选项时,将丢失在主机文件系统中写入文件的默认行为";

const form = formidable({
fileWriteStreamHandler: someFunction,
});

编辑:我的全部代码

import formidable from "formidable";
import { Writable } from "stream";
import { Buffer } from "buffer";
import { v4 as uuidv4 } from "uuid";

export const config = {
api: {
bodyParser: false,
},
};
const formidableConfig = {
keepExtensions: true,
maxFileSize: 10_000_000,
maxFieldsSize: 10_000_000,
maxFields: 2,
allowEmptyFiles: false,
multiples: false,
};
// promisify formidable
function formidablePromise(req, opts) {
return new Promise((accept, reject) => {
const form = formidable(opts);
form.parse(req, (err, fields, files) => {
if (err) {
return reject(err);
}
return accept({ fields, files });
});
});
}
const fileConsumer = (acc) => {
const writable = new Writable({
write: (chunk, _enc, next) => {
acc.push(chunk);
next();
},
});
return writable;
};
// inside the handler
export default async function handler(req, res) {
const token = uuidv4();
try {
const chunks = [];
const { fields, files } = await formidablePromise(req, {
...formidableConfig,
// consume this, otherwise formidable tries to save the file to disk
fileWriteStreamHandler: () => fileConsumer(chunks),
});
// do something with the files

const contents = Buffer.concat(chunks);
const bucketRef = storage.bucket("your bucket");
const file = bucketRef.file(files.mediaFile.originalFilename);
await file
.save(contents, {
public: true,
metadata: {
contentType: files.mediaFile.mimetype,
metadata: { firebaseStorageDownloadTokens: token },
},
})
.then(() => {
file.getMetadata().then((data) => {

const fileName = data[0].name;
const media_path = `https://firebasestorage.googleapis.com/v0/b/${bucketRef?.id}/o/${fileName}?alt=media&token=${token}`;
console.log("File link", media_path);

});
});
} catch (e) {
// handle errors
console.log("ERR PREJ ...", e);
}
}

这就是我解决这个问题的方法:

当我解析传入的表单多部分数据时,我可以访问文件的所有细节。因为它已经被解析并保存到服务器/我的计算机上的本地磁盘。因此,使用强大的路径变量,我使用节点内置的fs.unlink函数取消链接/删除该文件。当然,我在将文件保存到AWS S3后删除了它。

这是代码:

import fs from 'fs';
import formidable, { Files, Fields } from 'formidable';
const form = new formidable.IncomingForm();
form.multiples = true;
form.parse(req, async (err: any, fields: Fields, files: Files) => {
const pathArray = [];
try {
const s3Url = await util.uploadToS3(files);
// do something with the s3Url
pathArray.push(files.uploadFileName.path);
} catch(error) {
console.log(error)
} finally {
pathArray.forEach((element: string) => {
fs.unlink(element, (err: any) => {
if (err) console.error('error:',err);
});
});
}
})

我还找到了一个解决方案,你可以在这里看看,但由于架构的原因,如果发现在不更改我的原始代码的情况下实现有点困难(或者说我没有完全理解给定的实现(

相关内容

最新更新