节点文件系统在 post 路由上创建目录和文件
Node File System Create Directory and files on post route
我有一个生成 JSON 数据并将其保存为 .json 文件的仪表板。这最初是用 PHP 编写的,但由于各种原因,我们已经用 node.js 重写了应用程序。下面的代码获取 post 数据,然后应检查文件是否存在,如果确实存在则更新它,如果不存在则应创建文件和目录。
然而,它似乎只创建了第一个文件,我不明白为什么它不创建后续文件,因为这个 post 路由为每个 post 调用一次。
post 方法如下所示
$.ajax({
type : "POST",
url : '/save/',
dataType : 'json',
data : {
category : settings.category_id,
name : settings.campaignId,
json : JSON.stringify(settings)
}
});
我已经调试并且在调用时传递了所有正确的文件路径,但它几乎就像文件没有被写入数据一样。
在使用 node-inspector 和 nodemon 进行调试期间,代码循环遍历所有请求的新文件名并给出错误代码 ENOENT,因此它应该遵循创建文件路径。
如果您对节点和文件系统模块有所了解,并且愿意帮助我,那将是非常棒的,即使它只是向我指出更多教程的方向,...任何事情都会很棒!
-
'use strict'
const fs = require('fs');
const path = require('path');
const express = require('express');
const router = express.Router();
/* Save Data */
router.post('/', function(req, res) {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
let dir = 'public/savedData/' + req.body.category;
let filepath = dir + '/' + req.body.name + '.json';
fs.access(filepath, function(error) {
console.log(filepath);
console.log(error.code);
if (error) {
if (error.code == 'ENOENT') {
console.log(error.code);
//debugger;
// Create file since it doesn't exist
createFile(req, res, filepath);
} else {
//debugger;
console.log('access error:', error);
res.sendStatus(500);
}
} else {
//debugger;
// Update file since it already exists
updateFile(req, res, filepath);
}
});
});
function createFile(req, res, filepath) {
try {
let json = JSON.parse(req.body.json);
let output = JSON.stringify([json], null, 4);
fs.mkdir(path.dirname(filepath), function(error) {
if (error) {
if (error.code == 'EEXIST') {
updateFile(req, res, filepath);
} else {
res.sendStatus(500);
console.log('create file error :', error);
}
} else {
fs.writeFile(filepath, output, function(error) {
if (error) {
res.sendStatus(500);
console.log('write file error :', error);
} else {
res.sendStatus(200);
console.log('Data successfully saved');
}
});
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
function updateFile(req, res, filepath) {
try {
fs.readFile(filepath, 'utf-8', function(error, data) {
if (error) {
res.sendStatus(500);
console.log('update error:', error);
} else {
try {
let newJSON = JSON.parse(req.body.json);
let jsonArray = JSON.parse(data);
let output;
jsonArray.push(newJSON);
output = JSON.stringify(jsonArray, null, 4);
fs.writeFile(filepath, output, function(error) {
if (error) {
res.sendStatus(500);
console.log(error);
} else {
res.sendStatus(200);
console.log('Data successfully saved');
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
module.exports = router;
而不是检查文件是否存在,您应该尝试使用标志 wx
来编写,这会创建一个文件,但如果它已经存在则失败。这样你就不会让自己受制于比赛条件。我还建议包 mkdirp
,如果目录已经存在,它不会发出错误。
router.post('/', (req, res) => {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
const dirpath = `public/savedData/${req.body.category}`;
const filepath = `${dirpath}/${req.body.name}.json`;
mkdirp(dirpath, err => {
if (err) {
console.error('mkdirp failed', err);
return res.sendStatus(500);
}
const output = JSON.stringify([JSON.parse(req.body.json)]);
fs.writeFile(filepath, output, { flags: 'wx' }, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
);
});
确保清理 req.body.name
和 req.body.category
参数,因为您可能会将文件系统暴露给意外覆盖。
感谢@Iso,这是我的解决方案
router.post('/', (req, res) => {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
const dirpath = 'public/savedData/' + req.body.category;
const filepath = dirpath + '/' + req.body.name + '.json';
mkdirp(dirpath, err => {
if (err) {
console.error('mkdirp failed', err);
return res.sendStatus(500);
}
const output = JSON.stringify([
JSON.parse(req.body.json)
]);
fs.readFile(filepath, 'utf-8', function(error, data) {
if(error) {
fs.writeFile(filepath, output, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
} else {
let newJSON = JSON.parse(req.body.json);
let jsonArray = JSON.parse(data);
let output;
jsonArray.push(newJSON);
output = JSON.stringify(jsonArray, null, 4);
fs.writeFile(filepath, output, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
}
});
});
});
我有一个生成 JSON 数据并将其保存为 .json 文件的仪表板。这最初是用 PHP 编写的,但由于各种原因,我们已经用 node.js 重写了应用程序。下面的代码获取 post 数据,然后应检查文件是否存在,如果确实存在则更新它,如果不存在则应创建文件和目录。
然而,它似乎只创建了第一个文件,我不明白为什么它不创建后续文件,因为这个 post 路由为每个 post 调用一次。
post 方法如下所示
$.ajax({
type : "POST",
url : '/save/',
dataType : 'json',
data : {
category : settings.category_id,
name : settings.campaignId,
json : JSON.stringify(settings)
}
});
我已经调试并且在调用时传递了所有正确的文件路径,但它几乎就像文件没有被写入数据一样。
在使用 node-inspector 和 nodemon 进行调试期间,代码循环遍历所有请求的新文件名并给出错误代码 ENOENT,因此它应该遵循创建文件路径。
如果您对节点和文件系统模块有所了解,并且愿意帮助我,那将是非常棒的,即使它只是向我指出更多教程的方向,...任何事情都会很棒!
-
'use strict'
const fs = require('fs');
const path = require('path');
const express = require('express');
const router = express.Router();
/* Save Data */
router.post('/', function(req, res) {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
let dir = 'public/savedData/' + req.body.category;
let filepath = dir + '/' + req.body.name + '.json';
fs.access(filepath, function(error) {
console.log(filepath);
console.log(error.code);
if (error) {
if (error.code == 'ENOENT') {
console.log(error.code);
//debugger;
// Create file since it doesn't exist
createFile(req, res, filepath);
} else {
//debugger;
console.log('access error:', error);
res.sendStatus(500);
}
} else {
//debugger;
// Update file since it already exists
updateFile(req, res, filepath);
}
});
});
function createFile(req, res, filepath) {
try {
let json = JSON.parse(req.body.json);
let output = JSON.stringify([json], null, 4);
fs.mkdir(path.dirname(filepath), function(error) {
if (error) {
if (error.code == 'EEXIST') {
updateFile(req, res, filepath);
} else {
res.sendStatus(500);
console.log('create file error :', error);
}
} else {
fs.writeFile(filepath, output, function(error) {
if (error) {
res.sendStatus(500);
console.log('write file error :', error);
} else {
res.sendStatus(200);
console.log('Data successfully saved');
}
});
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
function updateFile(req, res, filepath) {
try {
fs.readFile(filepath, 'utf-8', function(error, data) {
if (error) {
res.sendStatus(500);
console.log('update error:', error);
} else {
try {
let newJSON = JSON.parse(req.body.json);
let jsonArray = JSON.parse(data);
let output;
jsonArray.push(newJSON);
output = JSON.stringify(jsonArray, null, 4);
fs.writeFile(filepath, output, function(error) {
if (error) {
res.sendStatus(500);
console.log(error);
} else {
res.sendStatus(200);
console.log('Data successfully saved');
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
});
} catch (error) {
res.sendStatus(500);
console.log(error);
}
}
module.exports = router;
而不是检查文件是否存在,您应该尝试使用标志 wx
来编写,这会创建一个文件,但如果它已经存在则失败。这样你就不会让自己受制于比赛条件。我还建议包 mkdirp
,如果目录已经存在,它不会发出错误。
router.post('/', (req, res) => {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
const dirpath = `public/savedData/${req.body.category}`;
const filepath = `${dirpath}/${req.body.name}.json`;
mkdirp(dirpath, err => {
if (err) {
console.error('mkdirp failed', err);
return res.sendStatus(500);
}
const output = JSON.stringify([JSON.parse(req.body.json)]);
fs.writeFile(filepath, output, { flags: 'wx' }, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
);
});
确保清理 req.body.name
和 req.body.category
参数,因为您可能会将文件系统暴露给意外覆盖。
感谢@Iso,这是我的解决方案
router.post('/', (req, res) => {
if (!(req.body.json && req.body.name && req.body.category)) {
res.sendStatus(400);
return;
}
const dirpath = 'public/savedData/' + req.body.category;
const filepath = dirpath + '/' + req.body.name + '.json';
mkdirp(dirpath, err => {
if (err) {
console.error('mkdirp failed', err);
return res.sendStatus(500);
}
const output = JSON.stringify([
JSON.parse(req.body.json)
]);
fs.readFile(filepath, 'utf-8', function(error, data) {
if(error) {
fs.writeFile(filepath, output, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
} else {
let newJSON = JSON.parse(req.body.json);
let jsonArray = JSON.parse(data);
let output;
jsonArray.push(newJSON);
output = JSON.stringify(jsonArray, null, 4);
fs.writeFile(filepath, output, err => {
if (err) {
console.error('writeFile failed', err);
return res.sendStatus(500);
}
console.log('Data successfully saved');
res.sendStatus(200);
});
}
});
});
});