使用 require vs fs.readFile 读取 json 文件内容

Read json file content with require vs fs.readFile

本文关键字:json 文件 读取 readFile require vs fs 使用      更新时间:2023-09-26

>假设对于来自 API 的每个响应,我需要将响应中的值映射到 Web 应用程序中的现有 json 文件,并显示来自 json 的值。在这种情况下,读取 json 文件的更好方法是什么?require或fs.readfile。请注意,可能同时有数千个请求传入。

请注意,我不希望在运行时对文件进行任何更改。

request(options, function(error, response, body) {
   // compare response identifier value with json file in node
   // if identifier value exist in the json file
   // return the corresponding value in json file instead
});

我想你会 JSON.parse json 文件进行比较,在这种情况下,require更好,因为它会立即解析文件并且它是同步的:

var obj = require('./myjson'); // no need to add the .json extension

如果您有数千个请求使用该文件,请在请求处理程序之外要求它一次,仅此而已:

var myObj = require('./myjson');
request(options, function(error, response, body) {
   // myObj is accessible here and is a nice JavaScript object
   var value = myObj.someValue;
   // compare response identifier value with json file in node
   // if identifier value exist in the json file
   // return the corresponding value in json file instead
});

fs.readFile有两个版本,它们是

异步版本

require('fs').readFile('path/test.json', 'utf8', function (err, data) {
    if (err) 
       // error handling
    var obj = JSON.parse(data);
});

同步版本

var json = JSON.parse(require('fs').readFileSync('path/test.json', 'utf8'));

使用 require 解析 json 文件,如下所示

var json = require('path/test.json');

但是,请注意

  • require是同步的并且只读取文件一次,则以下调用从缓存返回结果

  • 如果您的文件没有.json扩展名,require 不会将文件的内容视为JSON

由于没有人愿意编写基准测试,而且我有一种需要更快工作的感觉,所以我自己做了一个。

我比较了fs.readFile(

promisified版本(与require(没有缓存(与fs.readFileSync。

您可以在此处查看

基准测试,在此处查看结果。

对于 1000 次迭代,它如下所示:

require: 835.308ms
readFileSync: 666.151ms
readFileAsync: 1178.361ms

那么你应该使用什么呢?答案不是那么简单。

  1. 当您需要永久缓存对象时,请使用 require。最好使用 Object.freeze 来避免在应用程序中对其进行更改。
  2. 在单元测试或阻止应用程序启动时使用 readFileSync - 它是最快的。
  3. 当应用程序正在运行并且您不想阻止事件循环时,请使用 readFile 或承诺版本。

如果在测试中处理 JSON 夹具,请使用节点夹具。

该项目将查找一个名为 fixtures 的目录,该目录必须是测试目录的子目录才能加载所有 fixture(*.js 或 *.json 文件(:

// test/fixtures/users.json
{
  "dearwish": {
    "name": "David",
    "gender": "male"
  },
  "innaro": {
    "name": "Inna",
    "gender": "female"
  }
}
// test/users.test.js
var fx = require('node-fixtures');
fx.users.dearwish.name; // => "David" 

我只想指出,即使应该删除变量require它似乎也会将文件保存在内存中。我有以下情况:

for (const file of fs.readdirSync('dir/contains/jsons')) {
  // this variable should be deleted after each loop
  // but actually not, perhaps because of "require"
  // it leads to "heap out of memory" error
  const json = require('dir/contains/jsons/' + file);
}
for (const file of fs.readdirSync('dir/contains/jsons')) {
  // this one with "readFileSync" works well
  const json = JSON.parse(fs.readFileSync('dir/contains/jsons/' + file));
}

由于"堆内存不足"错误,具有require的第一个循环无法读取所有 JSON 文件。第二个循环与readFile有效。

如果文件为空,则 require 将中断。它将抛出一个错误:

语法错误...JSON 输入意外结束。

使用readFileSync/readFile您可以处理此问题:

let routesJson = JSON.parse(fs.readFileSync('./routes.json', 'UTF8') || '{}');

或:

let routesJson
fs.readFile('./dueNfe_routes.json', 'UTF8', (err, data) => {
    routesJson = JSON.parse(data || '{}');
});
{
  "country": [    
    "INDIA",
    "USA"
  ],
  "codes": [   
    "IN",
    "US"
  ]
}
// countryInfo.json
const { country, code } = require('./countryInfo.json');
console.log(country[0]); // "INDIA"
console.log(code[0]); // "IN"