使用文件的内容而不用 express.js 保存文件?

Posted

技术标签:

【中文标题】使用文件的内容而不用 express.js 保存文件?【英文标题】:Consume content of the file without saving the file with express.js? 【发布时间】:2018-11-17 02:04:48 【问题描述】:

我正在编写一个有 CVS 文件上传的应用程序。我有一个 CVS 解析器,所以我可以从我的前端将 CSV 上传到后端,对其进行处理并将其保存到数据库。之后,我正在删除文件。

我正在使用 multer 接受文件并将其保存到硬盘驱动器,然后我可以读取文件并使用文件的内容并删除文件。一切都很好。

我想知道是否有办法完全跳过实际保存文件。有没有一种简单的方法,只需从'multipart/form-data' 表单提交文件并使用 express 直接读取内容,而无需将其保存在文件系统上?

仅供参考,这就是我现在拥有的,它按预期工作

在前端:

static fileUpload(file) 
  const url = '/api/statement-upload';
  const formData = new FormData();
  formData.append('file', file);
  const config = 
    headers: 
      'content-type': 'multipart/form-data'
    
  ;
  return post(url, formData, config);

在我的快递服务器上,我正在使用 multer 并定义了这样的路由:

import multer from 'multer';

export default function (router) 
  const upload = multer(dest: 'uploads/');

  router.use('/api/statement-upload', upload.single('file'), (req, res) => 
    cvsParser(req.file.path)
      .then(() => res.json(error: false))
      .catch(e => res.json(error: e));
  );

  return router;
;

然后在我的 cvsParser 中有这个:

export default function (filePath) 
  let content = fs.readFileSync(filePath, 'binary');  
  fs.unlink(filePath, () => );

  // do nasty stuff to content and save it gently in the database

简而言之,有没有一种方法可以做到这一点,而不必在我可以使用文件内容之前将 CSV 保存到文件系统?

考虑到文件编码等,这是否可能,也许没有办法使用fs

【问题讨论】:

使用 multer 库,您可以将上传的文件存储在内存中,并将其用作缓冲区。在项目的自述文件中,您可以找到文档:github.com/expressjs/multer#memorystorage @FedericoB。这可能是我正在寻找的,只是错过了。但是,文件在内存中保留多长时间?如何在将其保存在变量/数据库中后立即清除内存? 根据此示例中显示的github.com/expressjs/multer/issues/337#issuecomment-217631329,似乎缓冲区临时存储在请求中,因此在请求处理结束时,我希望缓冲区从内存中清除 【参考方案1】:

当您不想将 csv 存储在文件系统中并读取内容时,可以这样做。就我而言,我必须将 csv 文件的内容作为字符串传递给另一台服务器(不保存在服务器的本地系统中)。

const multer = require('multer');
const upload = multer( storage: multer.memoryStorage() )

app.post(
        '/users/bulkUpload',
        upload.single('csvFile'),
        this.usersRoutes.uploadUserData
 );

uploadUserData():

uploadUserData = async(
    req: Request,
    res: Response,
    next: any
): Promise<any> => 
    try 
        const options = 
                formData : 
                    'upload': String(req.file.buffer)
                ,
                headers: 
                    authorization: req.token,
                    'Content-type': 'multipart/form-data'
                ,
                json: true
        ;
        const response = await this.http.post.exec(
                '/somePostUrl/',
                options
        );
        return res.status(200).json(response.body);
    catch (error) 
        return next(error);
    

在这里,console.log(String(req.file.buffer)) 会将 csv 文件的内容显示为字符串。

希望对你有帮助。

【讨论】:

【参考方案2】:

使用 multer 库,您可以将上传的文件存储在内存中,并将其用作缓冲区。在项目的自述文件中,您可以找到文档:github.com/expressjs/multer#memorystorage

【讨论】:

今晚我会试一试,看看会发生什么,将问题多留几个小时,看看是否有更多的想法/建议,但这看起来很有希望,谢谢。 你看到我在评论中指出的例子了吗?好像buffer的生命周期和request的生命周期有关。 请确定文件大小和请求数量,因为这可能会导致 outOfMemory 或内存泄漏类异常【参考方案3】:
    var csvtojson = require("csvtojson");
    app.post('/', async function (req, res) 
      let sampleFile = req.files.yourUploadedCsvFileName.data.toString();
      // convert it to JSON
      const json_data=await csvtojson().fromString(sampleFile);
      
    )

【讨论】:

以上是关于使用文件的内容而不用 express.js 保存文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Multer 重命名上传的文件不起作用 (Express.js)

将 HTML5 文本区域内容保存到文件

express.js 和 react.js cookie 保存到浏览器但不工作?

使用 express.js 动态加载路由

Express.js 不发送 css 文件

在 Express.js 中使用 PUT 方法