Javascript nodejs multer diskstorage在保存到磁盘后删除文件

Javascript nodejs multer diskstorage在保存到磁盘后删除文件,javascript,node.js,express,multer,Javascript,Node.js,Express,Multer,我正在使用Multiter diskstorage将文件保存到磁盘。 我首先将其保存到磁盘,并对该文件执行一些操作,然后使用另一个函数和lib将其上载到远程bucket。 一旦上传完成,我想从磁盘上删除它 var storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, '/tmp/my-uploads') }, filename: function (req, file,

我正在使用Multiter diskstorage将文件保存到磁盘。 我首先将其保存到磁盘,并对该文件执行一些操作,然后使用另一个函数和lib将其上载到远程bucket。 一旦上传完成,我想从磁盘上删除它

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, '/tmp/my-uploads')
  },
  filename: function (req, file, cb) {
    cb(null, file.fieldname + '-' + Date.now())
  }
})

var upload = multer({ storage: storage }).single('file')
下面是我如何使用它:

app.post('/api/photo', function (req, res) {
    upload(req, res, function (err) {
        uploadToRemoteBucket(req.file.path)
        .then(data => {
            // delete from disk first

            res.end("UPLOAD COMPLETED!");
        })
    })
});
如何使用diskStorage remove功能删除临时文件夹中的文件?

更新: 我已决定将其模块化,并将其放在另一个文件中:

const fileUpload = function(req, res, cb) {
    upload(req, res, function (err) {
        uploadToRemoteBucket(req.file.path)
        .then(data => {
            // delete from disk first

            res.end("UPLOAD COMPLETED!");
        })
    })
}

module.exports = { fileUpload };

您不需要使用
multer
来删除文件,而且
\u removeFile
是您不应该使用的私有函数

你会像平常一样删除这个文件。因此,无论您在哪里访问
req.file
,都可以执行以下操作:

const fs = require('fs')
const { promisify } = require('util')

const unlinkAsync = promisify(fs.unlink)

// ...

const storage = multer.diskStorage({
    destination(req, file, cb) {
      cb(null, '/tmp/my-uploads')
    },
    filename(req, file, cb) {
      cb(null, `${file.fieldname}-${Date.now()}`)
    }
  })

const upload = multer({ storage: storage }).single('file')

app.post('/api/photo', upload, async (req, res) =>{
    // You aren't doing anything with data so no need for the return value
    await uploadToRemoteBucket(req.file.path)

    // Delete the file like normal
    await unlinkAsync(req.file.path)

    res.end("UPLOAD COMPLETED!")
})

不需要穆特。只要使用这个代码

const fs = require('fs')

const path = './file.txt'

fs.unlink(path, (err) => {
  if (err) {
    console.error(err)
    return
  }

  //file removed
})

您也可以考虑使用此目的,在这个存储中,文件永远不会存储在磁盘中,而是存储在内存中,并且在执行控制器块执行之后,即在大多数情况下提供响应之后,自动从内存中删除。 当您使用此存储选项时,您将不会获得字段

file.destination
file.path
file.filename
,相反,您将获得一个字段
file.buffer
,顾名思义,它是一个缓冲区,您可以将此缓冲区转换为所需格式,以便对其执行操作,然后使用流对象上载

大多数流行的库都支持流,因此您应该能够使用流直接上载文件,用于将缓冲区转换为流的代码:

const Readable = require('stream').Readable;

var stream = new Readable();
stream._read = () => { }
stream.push(file.buffer);
stream.push(null);

// now you can pass this stream object to your upload function
这种方法效率更高,因为文件将存储在内存中,这将导致更快的访问,但它确实有一个缺点,如
multer
文档中所述:

警告:正在上载非常大的文件,或在中上载相对较小的文件 非常快的大数字可能会导致应用程序耗尽资源 使用内存存储时的内存


为了在所有路线上实现真正的自动化,我使用了以下策略:

当请求结束时,我们删除所有上传的文件(req.files)。在此之前,如果要将文件保存在服务器上,则需要将其保存在另一个路径中

var express = require('express');
var app = express();
var http = require('http');
var server = http.Server(app);

// classic multer instantiation
var multer = require('multer');
var upload = multer({
    storage: multer.diskStorage({
        destination: function (req, file, cb) {
            cb(null, `${__dirname}/web/uploads/tmp/`);
        },
        filename: function (req, file, cb) {
            cb(null, uniqid() + path.extname(file.originalname));
        },
    }),
});
app.use(upload.any());

// automatically deletes uploaded files when express finishes the request
app.use(function(req, res, next) {
    var writeHead = res.writeHead;
    var writeHeadbound = writeHead.bind(res);
    res.writeHead = function (statusCode, statusMessage, headers) {
        if (req.files) {
            for (var file of req.files) {
                fs.unlink(file.path, function (err) {
                    if (err) console.error(err);
                });
            }
        }

        writeHeadbound(statusCode, statusMessage, headers);
    };

    next();
});

// route to upload a file
    router.post('/profile/edit', access.isLogged(), async function (req, res, next) {
        try {

// we copy uploaded files to a custom folder or the middleware will delete them
            for (let file of req.files)
                if (file.fieldname == 'picture')
                    await fs.promises.copy(file.path, `${__dirname}/../uploads/user/photo.jpg`);

        } catch (err) {
            next(err);
        }
    });

谢谢你这个好的解决方案。但我决定把它拿出来,使它模块化。请查看更新。我如何在这里应用您的解决方案?谢谢你的建议这是一个很棒的解决方案+1表示使用prettify,+1表示我们只需要取消链接
req.file.path
。我刚刚学到了两个新东西(在看到这一点之前,从昨天开始,我就在promises中手动包装fs方法,以便与async Wait一起使用)。从Node 10.23.1开始,您可以使用
const fs=require('fs')。promises
开箱即用。res.end(“上载完成!”)后删除文件是否安全?因为那样的话,响应时间会提高。对那些不擅长承诺和承诺的人来说很有用-你需要为承诺和承诺添加一些定制,如果不需要的话,可能会让人困惑。