我们可以将 multer 配置为不在本地存储文件并且仅用于使用 req.files.image.path 吗?

Posted

技术标签:

【中文标题】我们可以将 multer 配置为不在本地存储文件并且仅用于使用 req.files.image.path 吗?【英文标题】:Can we configure multer to not store files locally and only for using req.files.image.path? 【发布时间】:2014-09-28 09:26:25 【问题描述】:

我的应用需求如下: 我将图像上传到 Cloudinary 并将图像的 url 存储在我的 mongodb 数据库中。

要将图像上传到 cloudinary,我需要提供文件路径,为此,我正在使用 multer。我使用以下语句:

app.use(multer( dest: './uploads/'));

我面临的问题是,每次我从本地系统将图像上传到 Cloudinary 上的数据库时,都会在“./uploads/”中创建一个本地副本。我不希望这种情况发生,因为我的图像在那里在 Cloudinary 上。

我读了documentation of multer,上面写着:

Multer 接受一个选项对象,其中最基本的是 dest 属性,它告诉 Multer 将文件上传到哪里。如果省略选项对象,文件将被重命名并上传到系统的临时目录。

我无法确定该临时上传空间是否需要清理或是否已处理。我的图像上传到 Cloudinary。我使用 multer 仅用于获取:

req.files.photo.path

工作。是否有任何其他方法可以做到这一点,或者是否可以将 multer 配置为不将图像存储到我的本地系统?

【问题讨论】:

您的问题解决了吗?我有同样的问题。他们的文档说使用内存存储作为存储选项而不是磁盘。我用过,但它不起作用。 @codeinprogress:是的,下面的答案对我也不起作用,这就是我没有接受它的原因。我在项目中的要求发生了变化,我对所占用的内存没问题。如果您找到解决此问题的方法,请发布答案。 必须直接询问 Cloudinary 人。 这不是 Cloudinary 特有的。 @codeinprogress:您是否尝试过以下 Ruslan 的回答?如果这不起作用,您可以在 multer 的回购中提出拉取请求,或者在 Github 上的 busboy 的回购中提出您的疑问。请在此处发布您的解决方案,以便将来对其他人有所帮助。 :) 是的,我的意思是 multer。我误写了cloudinary。他们告诉我什么都会在这里发布。 【参考方案1】:

2018 年 7 月:

因此,如果您想将图像存储到某种数据库中,您可能希望将其转换为缓冲区,然后将缓冲区插入数据库。如果你使用multer处理multipart表单(这里是你要上传的图片文件),你可以使用multermemoryStorage直接获取图片的缓冲区。换句话说:

var storage = multer.memoryStorage(); var upload = multer( storage: storage );

获取buffer:

使用内存存储时,文件信息将包含一个名为缓冲区的字段,该字段包含整个文件。

这意味着你可以从像req.files[0].buffer这样的命令中获取缓冲区


我在this repo更新了一个简单的repo,演示将图像上传到数据库而不复制到本地

【讨论】:

我查看了 multer 代码 (github.com/expressjs/multer),如果您不传递任何选项,我认为这实际上是默认设置。所以var upload = multer();应该相当于你的建议。 这与文档(npmjs.com/package/multer#multeropts)一致:“Multer 接受一个选项对象,其中最基本的是 dest 属性,它告诉 Multer 将文件上传到哪里。如果您省略选项对象,文件将保存在内存中,永远不会写入磁盘。”【参考方案2】:

来自 Multer 信息页面 https://www.npmjs.com/package/multer

如果 inMemory 选项为真 - 没有数据写入 磁盘,但数据保存在文件对象可访问的缓冲区中。

【讨论】:

当它说可以“运行到应用程序内存”时,这可能是服务器 RAM 的限制吗?它是自动“清除”,还是我们必须“清理”;手动记忆?【参考方案3】:

在 2016 年 7 月 14 日之前,您无法将 multer 配置为在本地存储文件。

但multer 只是busboy 的包装。所以,如果我们想避免撞到磁盘,我们可以尝试直接使用busboy。Connect-bubsboy会帮助我们:

app.use(busboy());

// request handler
req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) 
  file.on('end', function() 
    // do stuff with req.files[fieldname]
  );
);

2016 年 7 月 14 日更新

现在 multer 有MemoryStorage 将文件作为缓冲区存储在内存中。

var storage = multer.memoryStorage()
var upload = multer( storage: storage )

【讨论】:

我不知道这在过去是否属实,但现在 multer 提供了 memoryStorage() 对象,允许在内存中存储。【参考方案4】:

您也可以将文件上传到 Cloudinary 后删除。

// used to delete images from local directory
const fs = require('fs'); // gain access to file system
const util = require('util');
const deleteFile = util.promisify(fs.unlink); // unlink will delete the file

// in your post request
app.post('/images', upload.single('myFile'), async function(req, res) 
  const file = req.file; // multer gives access to the file object in the request
  // code to upload the file to Cloudinary
  await deleteFile(file.path); // remove locally stored image by passing the file's path  
);

【讨论】:

【参考方案5】:

如果您使用 Cloudinary 存储图像,请尝试使用 multer-storage-cloudinary

【讨论】:

以上是关于我们可以将 multer 配置为不在本地存储文件并且仅用于使用 req.files.image.path 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 multer 存储具有文件扩展名的文件?

通过表单从不同字段上传多个文件并使用express multer存储到mongodb数据库中

从请求将文件上传到云存储而不在本地保存

使用 multer 上传的文件存储在云端后如何删除?

MongoDB & Multer - 如何将缓冲区二进制文件转换为图像?

如何使用 multer 和 NodeJS 将图像上传到 GCS 存储桶?