使用Node.JS,如何将JSON文件读入(服务器)内存?


618

背景

我正在对Node.js进行一些试验,想从文本文件或.js文件(更好的??)中读取JSON对象到内存中,以便我可以从代码中快速访问该对象。我意识到那里有像Mongo,Alfred等的东西,但这不是我现在所需要的。

如何使用JavaScript / Node从文本或js文件中读取JSON对象并将其读入服务器内存中?


1
您如何称呼服务器内存?只要使它工作,nodejs脚本就可以工作,但是除非将nodejs脚本持久化,否则必须将数据存储在某个地方。
mpm 2012年

Answers:


1203

同步:

var fs = require('fs');
var obj = JSON.parse(fs.readFileSync('file', 'utf8'));

异步:

var fs = require('fs');
var obj;
fs.readFile('file', 'utf8', function (err, data) {
  if (err) throw err;
  obj = JSON.parse(data);
});

15
我认为JSON.parse是同步的,它直接来自v8,这意味着即使使用Async方式,人们也必须小心使用大型JSON文件。因为它会绑结节点。
Sean_A91

25
为了完整性。他们存在一个名为jsonfile的npm 。
Stefan

5
我不敢相信找到这个简单的东西是如此困难。我从Google得到的每个答案都是执行HTTPRequest或使用JQuery或在浏览器中执行
juliangonzalez

6
有两点:(1)同步答案应为let imported = require("file.json")。(2)JSON.parse必须是异步的,因为我使用此代码将70mb JSON文件作为对象加载到内存中。这种方法要花费毫秒,但是如果我使用require()它,它会产生波动
凯尔·贝克

8
对于在2019年及之后找到此答案的人们来说,Node.js通过拥有对许多版本的json支持,require如果您只想加载json文件,则此答案不再适用。随便使用let data = require('./yourjsonfile.json')就可以了(这本书的注释是,如果require的性能正在影响您的代码,则除了“想要加载
.json

392

我发现执行此操作的最简单方法是仅使用requireJSON文件的路径。

例如,假设您具有以下JSON文件。

test.json

{
  "firstName": "Joe",
  "lastName": "Smith"
}

然后,您可以使用以下命令轻松地将其加载到您的node.js应用程序中 require

var config = require('./test.json');
console.log(config.firstName + ' ' + config.lastName);

35
正是这样,人们才知道,如果我没记错的话,requirein节点将同步运行。在这里
prasanthv 2014年

@Ram对我有用,可能是您所在的位置test.json与他的示例不同。我正在使用node 5.0
guleria

18
这种方法的另一个问题/好处是,除非您专门删除了缓存的实例,否则缓存了必需的数据
magicode118 2016年

13
“要求”用于在应用程序的整个生命周期内加载要使用的模块或配置文件。似乎不适合使用它来加载文件。
亚基·克莱因

2
我想说这可能是安全威胁。如果您正在加载的json文件包含JS代码,require它将运行该代码吗?如果是这样,那么您确实需要控制json文件的来源,否则攻击者可能会在您的计算机上运行恶意代码。
sokkyoku

57

异步是有原因的!向@mihai扔石头

否则,这是他与异步版本一起使用的代码:

// Declare variables
var fs = require('fs'),
    obj

// Read the file and send to the callback
fs.readFile('path/to/file', handleFile)

// Write the callback function
function handleFile(err, data) {
    if (err) throw err
    obj = JSON.parse(data)
    // You can now play with your datas
}

9
同意:),还添加了异步
mihai 2012年

1
太棒了:-)虽然我不喜欢内联回调,但它可能导致我更希望避免的回调噩梦。
Florian Margaine '04年

9
它在那里是有原因的..除非您同步想要它。
马特·史蒂芬斯

40

至少在Node v8.9.1中,您可以执行

var json_data = require('/path/to/local/file.json');

并访问JSON对象的所有元素。


5
此方法仅加载一次文件。如果您要更改file.json之后的新需求(无需重新启动程序),则数据将来自首次加载。我没有消息来源对此提供支持,但是我正在构建的应用程序中具有此功能
LukasIgnatavičius18

您的答案很不完整。得到的是一个对象,甚至不必费心实现tostring()。
David A. Gray

3
@ DavidA.Gray该问题希望能够将对象作为对象而不是字符串进行访问。卢卡斯(Lukas)的单身人士中提到的这个答案很好。
mikemaccana

2
使用require也将在文件中执行任意代码。这种方法是不安全的,我建议您反对。
spoulson

16

在Node 8中,您可以使用内置的util.promisify()方法异步读取文件,如下所示

const {promisify} = require('util')
const fs = require('fs')
const readFileAsync = promisify(fs.readFile)

readFileAsync(`${__dirname}/my.json`, {encoding: 'utf8'})
  .then(contents => {
    const obj = JSON.parse(contents)
    console.log(obj)
  })
  .catch(error => {
    throw error
  })

3
.readFile已经是异步的,如果您要查找同步版本,其名称为.readFileSync
奥特纳斯

如果要使用Promisefs/promises,从Node 10开始也要使用。注意:API是实验性的:nodejs.org/api/fs.html#fs_fs_promises_api
aboutaaron

@Aternus .readFile异步的,但不是async。意思是,该函数未使用async关键字定义,也未返回Promise,因此您无法执行此操作await fs.readFile('whatever.json');
Kip

@Kip CodeSandBox怎么样?
Aternus

7

使用node-fs-extra (异步等待)

const readJsonFile = async () => {
  try {
    const myJsonObject = await fs.readJson('./my_json_file.json');
    console.log(myJsonObject);
  } catch (err) {
    console.error(err)
  }
}

readJsonFile() // prints your json object

6

使用fs-extra软件包非常简单:

同步:

const fs = require('fs-extra')

const packageObj = fs.readJsonSync('./package.json')
console.log(packageObj.version) 

异步:

const fs = require('fs-extra')

const packageObj = await fs.readJson('./package.json')
console.log(packageObj.version) 

3
function parseIt(){
    return new Promise(function(res){
        try{
            var fs = require('fs');
            const dirPath = 'K:\\merge-xml-junit\\xml-results\\master.json';
            fs.readFile(dirPath,'utf8',function(err,data){
                if(err) throw err;
                res(data);
        })}
        catch(err){
            res(err);
        }
    });
}

async function test(){
    jsonData = await parseIt();
    var parsedJSON = JSON.parse(jsonData);
    var testSuite = parsedJSON['testsuites']['testsuite'];
    console.log(testSuite);
}

test();


0

如此众多的答案,而且没人能以基准测试来比较同步,异步和需求。我通过要求,readFileSync和READFILE在内存中所描述的不同使用情况下读取JSON的位置


-1

如果您正在寻找用于通过错误处理Async加载JSON文件的完整解决方案Relative Path

  // Global variables
  // Request path module for relative path
    const path = require('path')
  // Request File System Module
   var fs = require('fs');


// GET request for the /list_user page.
router.get('/listUsers', function (req, res) {
   console.log("Got a GET request for list of users");

     // Create a relative path URL
    let reqPath = path.join(__dirname, '../mock/users.json');

    //Read JSON from relative path of this file
    fs.readFile(reqPath , 'utf8', function (err, data) {
        //Handle Error
       if(!err) {
         //Handle Success
          console.log("Success"+data);
         // Parse Data to JSON OR
          var jsonObj = JSON.parse(data)
         //Send back as Response
          res.end( data );
        }else {
           //Handle Error
           res.end("Error: "+err )
        }
   });
})

目录结构:

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.