使用nodejs将文件写入特定目录并将其上传到数据库

Posted

技术标签:

【中文标题】使用nodejs将文件写入特定目录并将其上传到数据库【英文标题】:Writing a file with nodejs into a specific direoctory and upload it to database 【发布时间】:2021-08-07 03:57:43 【问题描述】:

您好,我正在使用 nodejs、express 和 mongodb 为数据库上传文件 这是我的 POST API 使用 multer 在我的数据库中创建一个新文件

router.post('/create',multer( storage : storage).any(), (req, res) => 
    var sample = fs.readFileSync('./uploads/'+req.files[0].filename,'utf8');
    function Filetostring() 
        let arr = sample.split(/\r?\n/);
        // Find returns the first element that matches our criteria
        const step = arr.filter((step , idx)=> 
            if (step.includes("step")) 
             console.log(step);             //this gives me the first result I need
    
             return true;
    
            
            return false;
         ); 
       let stepss = JSON.stringify(step)
       let newString = stepss.replace(/[\[\]\'\s]/g, ' ');
       let newString2 = newString.replace(/"/g, '');
       let newString3 = newString2.replace(/#step/g, '');
       let newString4 = newString3.replace(/,/g, '\n');

       return newString4;
     

     let newName = JSON.stringify(req.files[0].filename)
     let newName1 = newName.replace(/"/g, '');
     let newName2 = newName1.replace(/.robot/g, '');
     let steps = Filetostring()
     console.log(steps)

    
    var tc = new Testcase(
        name: newName2,
        upload: req.files[0].filename ,
        run : steps,
        modify: req.body.modify,
        delete: req.body.delete,
        step1: req.body.step1,
        step2: req.body.step2,
        step3: req.body.step3,
        step4: req.body.step4,
        step5: req.body.step5,
        step6: req.body.step6,
        step7: req.body.step7,
    );
    
    //const file = req.file;
    console.log(req.files[0].filename);
    tc.save((err, doc) => 
        if (err)  res.status(401).send("errorrrrr") 
        else  
            res.status(200).send(doc)
        
    );
);

文件上传工作正常,但我想添加一个函数来编写新文件而不是上传现有文件 例如,我使用表单编写文本(假设我填写变量 step1)并将其存储到 ./uploads/name.txt

我看到有一个名为 fs.writeFilefs 函数,但我不知道如何正确实现它,所以它会自动保存我输入的文本我的变量到一个文件中

我试过了,但它给了我一个“errorrrrr”:

upload: fs.writeFile('./uploads/'+req.body.name+'.robot', req.body.step1 , function (err) 
            if (err) throw err;               console.log('Results Received');
          ),

如果我使用:

upload: fs.writeFile('./uploads/aa.robot', 'hello' , function (err) 
            if (err) throw err;               console.log('Results Received');
          ),

我在添加新测试用例时出错,但文件已上传 aa.robot,其中实际上是我需要的文本 hello

这是我的 API 现在的样子:

router.post('/create2', (req, res) => 
     
    
    var tc = new Testcase(
        name: req.body.name,
        upload: fs.writeFile('./uploads/aa.robot', 'hello' , function (err) 
            if (err) throw err;               console.log('Results Received');
          ),
        
        run : req.body.run,
        
        modify: req.body.modify,
        delete: req.body.delete,
        step1: req.body.step1,
        step2: req.body.step2,
        step3: req.body.step3,
        step4: req.body.step4,
        step5: req.body.step5,
        step6: req.body.step6,
        step7: req.body.step7,
    );
    
    tc.save((err, doc) => 
        if (err)  res.status(401).send("errorrrrr") 
        else  
            res.status(200).send(doc)
        
    );
);

【问题讨论】:

所以您想将使用上传文件创建的测试用例文档编写为另一个 .json 文件,对吗? 不,我想要一个选项来编写测试用例并将其导出为文件 .txt 或 .robot 现在我只能上传现有文件 哦,好吧,那么您有几种方法可以获取“写入为文件”选项,例如,您可以要求您的客户添加此选项以请求正文,如 "save": true 或查询参数,如 @987654326 @。您需要在路由处理程序中实现此逻辑,然后将文件保存(写入)到您要存储它的路径。写作部分我可以帮你,选项部分看你的选择。 谢谢,我用我尝试过的东西编辑了我的帖子(只是尝试一下)它给了我一个错误,但同时文件“results.txt”被成功导出 好。你遇到了什么错误?您可以选择使用JSON.stringify(tc.toObject()) 作为fs.writeFile() 实现的数据参数,因此您可以将测试用例文档作为字符串写入.txt 文件。这就是你想要的吗? 【参考方案1】:

这是 POST 路由处理程序的正确实现。你做错了什么是你试图在你的测试用例文档中将上传字段的值设置为fs.writeFile()的函数。如果你有一个正确的 Mongoose schame 来验证你的 Testcase 文档,那么这个上传字段的值将会失败。当然,如果那不是你想要的,但我想不是。

这是您的 POST 路由处理程序的正确实现:

router.post('/create',multer( storage : storage).any(), (req, res) => 
    var sample = fs.readFileSync('./uploads/'+req.files[0].filename,'utf8');
    function Filetostring() 
        let arr = sample.split(/\r?\n/);
        // Find returns the first element that matches our criteria
        const step = arr.filter((step , idx)=> 
            if (step.includes("step")) 
             console.log(step);             //this gives me the first result I need
    
             return true;
    
            
            return false;
        ); 
        let stepss = JSON.stringify(step)
        let newString = stepss.replace(/[\[\]\'\s]/g, ' ');
        let newString2 = newString.replace(/"/g, '');
        let newString3 = newString2.replace(/#step/g, '');
        let newString4 = newString3.replace(/,/g, '\n');

        return newString4;
     

    let newName = JSON.stringify(req.files[0].filename)
    let newName1 = newName.replace(/"/g, '');
    let newName2 = newName1.replace(/.robot/g, '');
    let steps = Filetostring();

    
    var tc = new Testcase(
        name: newName2,
        upload: req.files[0].filename,
        run : steps,
        modify: req.body.modify,
        delete: req.body.delete,
        step1: req.body.step1,
        step2: req.body.step2,
        step3: req.body.step3,
        step4: req.body.step4,
        step5: req.body.step5,
        step6: req.body.step6,
        step7: req.body.step7,
    );

    let saveFlag = req.query.save && req.query.save.trim().toLowerCase() === 'true'
        ? true
        : false;
    
    tc.save((err, doc) => 
        if (err)  res.status(401).send("errorrrrr") 
        else 
            if(saveFlag) 
                let data = JSON.stringify(doc.toObject());
                fs.writeFile(`./uploads/filename.txt`, data, (err) => 
                    if(err) res.status(500).send(err.message);
                    else res.status(200).send(doc);
                );
             else 
                res.status(200).send(doc);
            
        
    );
);

这里我设置upload: req.files[0].filename就像你原来的实现一样,它会取文件名已经上传到你的存储中。然后在几行之后,我创建了saveFlag 变量来检查您的客户是否希望您保存测试用例文档。在底部,在tc.save((err, doc) => ...) 的回调中,我实现了一个fs.writeFile() 函数,它取决于名为save 的查询参数。您对 API 的请求应该类似于 POST http://hostname:port/api/router/create?save=true。它的数据是字符串化的测试用例文档。您可以使用要写入文件的内容更改该数据。

【讨论】:

以上是关于使用nodejs将文件写入特定目录并将其上传到数据库的主要内容,如果未能解决你的问题,请参考以下文章

使用 Websockets 和 Nodejs 上传文件

使用 Puppeteer 如何从目录上传随机文件并将其删除?

如何将文件写入 NodeJS 中的特定目录?

如何将图像从前端(reactjs)传递到后端(nodejs)并将其上传到firebase存储?

使用NodeJS,如何将文件上传到azure容器/目录(如:test-container/folder-test)

使用 NodeJS 中的特定路径将文件上传到 AWS S3