我想阅读Meteor应用程序中文件夹内的所有json文件。
我有以下结构:
/server
-- /methods
-- -- file1.json
-- -- file2.json
我尝试使用以下代码读取所有JSON文件:
var fs = Npm.require('fs');
var path = Npm.require('path');
var base = path.resolve('.');
try {
var files = fs.readdirSync(base + '/methods/*.json');
console.log(files);
} catch (e) {
console.dir(e)
}
但这不起作用,它向我显示错误,指出目录或文件不存在。
我犯了一些错误吗?或者还有另一种方法吗?
答案 0 :(得分:2)
首先,请注意查找Meteor的项目根目录,因为path.resolve('.')
甚至process.env.PWD
的结果可能会在不同的部署设置中发生变化。
其次,fs.readdirSync(path)
的参数path
需要一个目录。因此,正确的呼叫将是var files = fs.readdirSync(base + '/server/methods/');
。
但是,我建议使用Assets
。只需将您的JSON文件移至private
目录,然后通过Assets.getText(assetPath, [asyncCallback])
或Assets.getBinary(assetPath, [asyncCallback])
在服务器上访问它们。
例如:
if (Meteor.isServer) {
Meteor.startup(function() {
var example1 = JSON.parse(Assets.getText('methods/example1.json'));
var example2 = JSON.parse(Assets.getText('methods/example2.json'));
console.log(example1);
console.log(example2);
});
}
如果您想阅读所有 JSON文件,可能需要以下解决方法:
if (Meteor.isServer) {
Meteor.startup(function() {
var exec = Npm.require('child_process').exec;
var files = [],
fileNames = [];
exec('ls -m assets/app/methods | tr -d \' \n\' ', Meteor.bindEnvironment(function(error, stdout, stderr) {
if (error !== null) {
console.log('exec error: ' + error);
}
fileNames = stdout.split(',');
/* Print all file names. */
console.log("File names:");
console.log(fileNames);
_.each(fileNames, function(fileName) {
/* Check if file has proper extension. */
if (fileName.split('.').pop() == 'json') files.push(JSON.parse(Assets.getText('methods/' + fileName)));
});
/* Print all JSON files. */
_.each(files, function(file) {
console.log(file);
});
}));
});
}
如果您想同步进行exec
来电,则可能需要使用Meteor.wrapAsync(func, [context])
:
if (Meteor.isServer) {
var exec = Npm.require('child_process').exec;
var files = [], fileNames = [];
var execAsync = function (options, callback) {
console.log("execAsync()");
exec('ls -m assets/app/methods | tr -d \' \n\' ', Meteor.bindEnvironment(function (error, stdout, stderr) {
if (error !== null) {
console.log('exec error: ' + error);
}
fileNames = stdout.split(',');
/* Print all file names. */
console.log("File names:");
console.log(fileNames);
_.each(fileNames, function (fileName) {
/* Check if file has proper extension. */
if (fileName.split('.').pop() == 'json') files.push(JSON.parse(Assets.getText('methods/' + fileName)));
});
callback(null, options.callback);
}));
};
function postProcessing(callback) {
console.log("postProcessing()");
/* Print all JSON files. */
_.each(files, function (file) {
console.log(file);
});
callback();
}
Meteor.startup(function () {
/* Wrap asynchronous exec function, in order to call it in a synchronous style. */
var execSync = Meteor.wrapAsync(execAsync);
var refToPostProcessing = execSync({callback: postProcessing});
var postProcessingSync = Meteor.wrapAsync(refToPostProcessing);
postProcessingSync();
});
}
这是我的服务器输出:
I20150919-09:27:09.189(2)? execAsync()
I20150919-09:27:09.210(2)? File names:
I20150919-09:27:09.213(2)? [ 'example1.json', 'example2.json' ]
I20150919-09:27:09.215(2)? postProcessing()
I20150919-09:27:09.217(2)? { name: 'Product',
I20150919-09:27:09.217(2)? properties:
I20150919-09:27:09.218(2)? { id:
I20150919-09:27:09.218(2)? { type: 'number',
I20150919-09:27:09.218(2)? description: 'Product identifier',
I20150919-09:27:09.218(2)? required: true },
I20150919-09:27:09.218(2)? name:
I20150919-09:27:09.218(2)? { description: 'Name of the product',
I20150919-09:27:09.219(2)? type: 'string',
I20150919-09:27:09.219(2)? required: true },
I20150919-09:27:09.219(2)? price: { type: 'number', minimum: 0, required: true },
I20150919-09:27:09.219(2)? tags: { type: 'array', items: [Object] } } }
I20150919-09:27:09.220(2)? { red: '#f00',
I20150919-09:27:09.221(2)? green: '#0f0',
I20150919-09:27:09.221(2)? blue: '#00f',
I20150919-09:27:09.221(2)? cyan: '#0ff',
I20150919-09:27:09.221(2)? magenta: '#f0f',
I20150919-09:27:09.221(2)? yellow: '#ff0',
I20150919-09:27:09.221(2)? black: '#000' }
假设您有以下结构:
your-meteor-project
├── .meteor
├── server
├── private
│ └── methods
│ └── example1.json
│ └── example2.json
└── …
答案 1 :(得分:0)
根据上面 Matthias Eckhart 的回答,我编写了一个方法来将所有 csv 文件加载到一个文件夹中,将内容转换为 JSON 并将数据作为对象返回给客户端,每个 csv 文件都有一个子对象。我将其发布在这里以防对其他人有所帮助:使用资产和方法以及将 csv 转换为 JSON 时会出现一些问题。
import CSVToJSON from 'csvtojson';
if (Meteor.isServer) {
const getParameterFilenames = (options, callback) => {
// read the contents of the 'private/parameters' folder
const { exec } = Npm.require('child_process');
// "ls -m" will return directories as well as folders, so make sure to filter the results before loading files
exec('ls -m assets/app/parameters | tr -d \' \n\' ', Meteor.bindEnvironment((error, stdout, stderr) => {
if (error !== null) {
console.log(`Error in getParameterFilenames: ${error}`);
}
const filenames = stdout.split(',');
callback(null, filenames);
}));
};
Meteor.methods({
'loadParameters'() {
const syncFunc = Meteor.wrapAsync(getParameterFilenames);
const filenames = syncFunc({});
// load parameters from csv files in 'private/parameters'
// this will be assets/app/parameters in the built app
// csv file contains key / value pairs
// first row is key, second row is value
// first key must be propertyName which will be the key for this sheet's child object in parameters, e.g.:
/*
"propertyName","value1","value2"
"map",10,20
*/
const promises = [];
const filesData = [];
// although Assets.getText is used synchronously, the files must be retrieved before creating the promises
filenames.forEach((filename) => {
if (filename.split('.').pop() === 'csv') {
filesData.push(Assets.getText(`parameters/${filename}`));
}
});
filesData.forEach((data) => {
promises.push(CSVToJSON().fromString(data));
});
// Meteor will wait for Promise.all to resolve before returning the result to the client
return Promise.all(promises)
.then((results) => {
// aggregate results into an object
const parameters = {};
results.forEach((result) => {
const data = result[0];
const parameter = { ...data };
delete parameter.propertyName;
parameters[data.propertyName] = parameter;
});
return parameters;
});
},
});
}