读取JSON文件的有效方法?

Posted

技术标签:

【中文标题】读取JSON文件的有效方法?【英文标题】:Efficient way to read JSON file? 【发布时间】:2019-06-16 15:30:14 【问题描述】:

我在 Nodejs 中看到了从本地读取 JSON 文件的不同方法。像这样;

    方法

    使用 fs 库

    同步

    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);
    );
    

    来源:https://***.com/a/10011078/7724032

    方法

    使用 require()

    let data = require('/path/file.json');
    

    方法

    使用 Ajax 请求 How to retrieve data from JSON file using Jquery and ajax?

可能还有其他方法。但是我听说使用方法 1 读取 JSON 文件时比其他方法更有效。

我正在开发一个模块,当每个客户端请求时我必须读取一个 JSON 文件,并且我当前使用方法 1。这是银行应用程序,性能很重要。所以帮我找到使用这个senario的好方法?

谢谢,任何帮助将不胜感激!

【问题讨论】:

如果您不需要 fs,并且希望它同步,使用 require 是最有效的,因为它可以节省内存。如果您不需要 fs 并且希望它异步,则使用 xmlHttpRequest 是最有效的。如果您需要 fs 来处理其他事情,那么 fs 在任何一种情况下都是最有效的方法,因为一旦加载它就比 require 快,而且它的时间成本比 xmlHttpRequest @Asthmatic 太好了,谢谢!这个答案会很有帮助。 :) 如果您正在处理大型 JSON,那么迄今为止最大的瓶颈将是 JSON.parse 本身。它要求您将整个文件加载到 String 中(另外,javascript 使用 UTF16,因此内存使用量增加了一倍)并且盲目的 JSON 解析非常慢。如果您的输入是数组或字典,您可以 1) 流式传输 JSON 解析,以便在加载整个文件之前开始工作,2) 在解析时过滤,以便只生成所需的对象。 【参考方案1】:

所以我创建了一个大的 json 文件并测量了时间以查看哪个更快,创建文件的代码在最后并注释。

const fs = require('fs')

// method 1 - sync
console.time('method_1_sync ')
var obj = JSON.parse(fs.readFileSync('file.json', 'utf8'))
console.log(obj[1000] === 2000)
console.timeEnd('method_1_sync ')

// method 2
console.time('method_2      ')
let data = require('./file.json')
console.log(data[1000] === 2000)
console.timeEnd('method_2      ')

// method 1 - aysnc
console.time('method_1_async')
fs.readFile('file.json', 'utf8', function (err, data) 
  if (err) throw err
  data = JSON.parse(data)
  console.log(data[1000] === 2000)
  console.timeEnd('method_1_async')
)

/*
var obj = 

for (i=0; i < 1000000; i++)
  obj[i] = i+i


var json = JSON.stringify(obj)
fs.writeFile('file.json', json, function() )
*/

这是我机器上的结果:

method_1_sync : 131.861ms
method_2      : 131.510ms
method_1_async: 130.521ms

method_1_async 似乎是最快的。方法 3 由于网络延迟,不值得测试。

【讨论】:

这是一个非常糟糕的测试用例,没有任何意义。您应该将整个过程运行数千次并测量平均时间。【参考方案2】:

方法 3) 不在考虑之列,因为它将其他方法之一与网络请求相结合,因此您仍然必须选择其他方法之一。

我假设方法 2) 正在泄漏内存。如果您需要两次,NodeJS 将通过引用返回完全相同的内容:

 require("thing") === require("thing")

因此,如果您需要某个东西一次,它将永远留在记忆中。如果你多次查找它会很快,但如果你有很多文件,它会填满内存。

现在只剩下方法 1),我会使用异步版本,因为它可以并行执行多个请求,如果您的服务器处于负载状态,它将优于同步方法。


我个人会选择选项 4):

将其存储在数据库中。数据库将数据加载到内存中以便更快地访问,并且它们是为处理大量文件而构建的。当您处理 JSON 时,Mongodb 将是一个不错的选择:

 const db = mongodb.collection("json");

 function getFile() 
    return db.findOne( "name": "test" );
 

【讨论】:

这是一个更好的答案。 @乔纳斯·威尔姆斯【参考方案3】:

我回答了这个问题并添加了比较 require 与 readFile 与 readFileSync here 的基准。

【讨论】:

以上是关于读取JSON文件的有效方法?的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中读取大量 json 文件?

vite2 读取json文件的几种方法

Spark SQL 读取已转义双引号的 JSON 文件

Spark - 如何从 S3 读取具有文件名的多个 Json 文件

如何搜索 JSON 文件? [关闭]

读取和存储 JSON 数据的有效方法