简体   繁体   English

节点上传的图像保存 - 流与缓冲区

[英]Node uploaded image save - stream vs buffer

I am working on image upload and don't know how to properly deal with storing the received file.我正在处理图像上传,不知道如何正确处理存储接收到的文件。 It would be nice to analyze the file first if it is really an image or someone just changed the extension.如果文件确实是图像或有人刚刚更改了扩展名,那么首先分析文件会很好。 Luckily I use package sharp which has exactly such a feature.幸运的是,我使用了具有这种功能的 package sharp I currently work with two approaches.我目前使用两种方法。

Buffering approach缓冲方法

I can parse multipart form as a buffer and easily decide whether save a file or not.我可以将多部分表单解析为缓冲区并轻松决定是否保存文件。

const metadata = await sharp(buffer).metadata();
if (metadata) {
  saveImage(buffer);
} else {
  throw new Error('It is not an image');
}

Streaming approach流式方法

I can parse multipart form as a readable stream.我可以将多部分形式解析为可读流。 First I need to forward the readable stream to writable and store file to disk.首先,我需要将可读流转发到可写并将文件存储到磁盘。 Afterward, I need again to create a readable stream from saved file and verify whether it is really image.之后,我需要再次从保存的文件中创建一个可读流并验证它是否真的是图像。 Otherwise, revert all.否则,全部还原。

// save uploaded file to file system with stream
readableStream.pipe(createWriteStream('./uploaded-file.jpg'));

// verify whether it is an image
createReadStream('./uploaded-file.jpg').pipe(
  sharp().metadata((err, metadata) => {
    if (!metadata) {
      revertAll();
      throw new Error('It is not an image');
    }    
  })
)

It was my intention to avoid using buffer because as I know it needs to store the whole file in RAM.我打算避免使用缓冲区,因为我知道它需要将整个文件存储在 RAM 中。 But on the other hand, the approach using streams seems to be really clunky.但另一方面,使用流的方法似乎非常笨拙。

Can someone help me to understand how these two approaches differ in terms of performance and used resources?有人可以帮助我了解这两种方法在性能和使用的资源方面有何不同吗? Or is there some better approach to how to deal with such a situation?还是有更好的方法来处理这种情况?

In buffer mode, all the data coming from a resource is collected into a buffer , think of it as a data pool, until the operation is completed;在缓冲模式下,来自一个资源的所有数据都被收集到一个buffer中,将其视为一个数据池,直到操作完成; it is then passed back to the caller as one single blob of data.然后将其作为单个数据块传递回调用者。 Buffers in V8 are limited in size. V8 中的缓冲区大小有限。 You cannot allocate more than a few gigabytes of data, so you may hit a wall way before running out of physical memory if you need to read a big file.您不能分配超过几 GB 的数据,因此如果您需要读取一个大文件,您可能会在耗尽物理内存之前碰壁。

On the other hand, streams allow us to process the data as soon as it arrives from the resource.另一方面,流允许我们在数据从资源到达时立即对其进行处理。 So streams execute their data without storing it all in memory.因此流执行它们的数据而不将其全部存储在内存中。 Streams can be more efficient in terms of both space (memory usage) and time (computation clock time).流在空间(内存使用)和时间(计算时钟时间)方面都可以更有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM