在 Node.js 下存储 JSON 的简单方法

Posted

技术标签:

【中文标题】在 Node.js 下存储 JSON 的简单方法【英文标题】:Easy way to store JSON under Node.js 【发布时间】:2013-02-03 01:26:22 【问题描述】:

我正在寻找一种超级简单的方法来在 Node.js 下以持久的方式存储一个 JSON 数组。它不需要有任何特殊功能。我只想在其中放一个 JSON 对象,以便在下次服务器重启时读取它。

(像 MongoDBCouchDB 这样的解决方案对于这个目的来说似乎都过大了。)

【问题讨论】:

没有“JSON 对象”这样的东西。要么你有一个对象(这里:javascript 对象),要么你有 JSON - 这是一个字符串。你可以用正常的方式保存这个字符串——文件、数据库... 【参考方案1】:

为什么不写入文件?

// Writing...
var fs = require("fs");
var myJson = 
    key: "myvalue"
;

fs.writeFile( "filename.json", JSON.stringify( myJson ), "utf8", yourCallback );

// And then, to read it...
myJson = require("./filename.json");

请记住,如果您需要反复读写,则必须为您反复读取的每个文件清除 Node 的缓存,否则 Node 将不会重新加载您的文件,而是产生它在读取期间看到的内容第一个require 电话。幸运的是,清除特定需求的缓存非常容易:

delete require.cache[require.resolve('./filename.json')]

另外请注意,如果(从 Node 12 开始)您使用的是 ES 模块而不是 CommonJS,import 语句没有相应的缓存失效。相反,请使用dynamic import(),然后由于导入来自 URL,您可以添加查询字符串作为缓存清除的一种形式,作为导入字符串的一部分。

或者,为了避免任何内置缓存,使用 fs.readFile()/fs.readFileSync() 而不是 require(如果你正在编写基于 Promise 的代码,则使用 fs/promises 而不是 fs,无论是显式地还是隐式地使用异步/等待)

【讨论】:

只需添加一件事:如果您“要求”该文件,则必须信任其内容。 JSON 作为数据交换格式通常不受信任,如果您从外部源获取 JSON,请始终使用 JSON 解析方法。我这样说只是为了防止这种(读取)模式被记住为所有 JSON 内容的共同点。 是的,但我认为验证必须在写入之前完成,而不是在阅读时完成。 实际上,整个 Rails 堆栈的作用正好相反 - 永远不要信任数据库中的任何内容,而且无论您对 Rails 有何看法,他们采用该策略是有原因的。 我从来没有使用过 Ruby,所以我对此一无所知 :D 另外,数据的安全性是问题作者未指定的。 不,我没有这么说。恕我直言,这里的问题总是有两个组成部分:对于提出问题的人以及后来在输入相关问题时找到它们的所有那些人。此外,我提到的 Rails 政策与实施 Rails 的语言没有任何关系。这是一个通用的 Web 应用程序设计原则。一遍又一遍 - 正如我所说,我只是为后代添加了评论,我并没有在这种情况下批评你的回答,所以让我们就这样吧,没有理由变得防御。【参考方案2】:

试试 NeDB:https://github.com/louischatriot/nedb

"Node.js 的嵌入式持久化数据库,用 Javascript 编写,没有依赖项(当然 npm 模块除外)。您可以将其视为 Node.js 项目的 SQLite,可以与简单的 require 语句一起使用. API 是 MongoDB 的子集。您可以将其用作持久性或仅内存中的数据存储。”

【讨论】:

给未来访问者的注意事项:上述库最后一次更新是在 2015 年,此后已被正式弃用。【参考方案3】:

我找到了一个名为 json-fs-store 的库,用于将 JavaScript 对象序列化为文件中的 JSON 并稍后检索它。

当通过store.load 方法(目前未在文档中描述)检索文件时,将使用JSON.parse 进行解析,这比在其他答案中使用require 更好:

当内容格式错误时,您会得到适当的错误处理 如果有人设法将 JavaScript 代码偷偷带入文件中,则会导致解析错误,而不是执行 JS。

【讨论】:

给未来访问者的注意事项:上述库自 Node v0.4 起就没有跟上 Node 的步伐,应该/不能与当前版本的 Node 一起使用。【参考方案4】:

如果您正在寻找性能考虑:LokiJS

https://www.npmjs.com/package/lokijs

http://lokijs.org/#/

【讨论】:

【参考方案5】:

如果您需要简单的数据存储,无需外部进程,性能非常高且稳定,您可能会喜欢Rocket-store。使用非常简单,包含模块就可以马上开始插入记录了。

主要有三种方法:putgetdelete(以及一些特殊的方法和选项设置)

示例:

// collection/table = "cars", key = "Mercedes"
result = await rs.post("cars", "Mercedes", owner: "Lisa Simpson", reg: "N3RD");

// Get all records from "cars" collection
result = await rs.get("cars","*");

// Delete records in collection "cars" where keys match "*cede*"
result = await rs.delete("cars","*cede*");

它依靠底层文件系统缓存来优化速度,并且可以处理数百万条记录。

您可以获得简单的序列、自动递增和其他次要便利,但仅此而已。没有什么花哨。我非常喜欢它,当我需要一个简单的存储解决方案时,但我也非常有偏见,作为作者;)

【讨论】:

比Nedb 有什么优势? 有几件事;主要是简单和速度。在任何地方都找不到比 Rocket-store 更简单的 API。你甚至不需要初始化任何东西就可以开始发布到它。它非常有效地使用操作系统文件缓存。只有瓶颈是 libuv 中底层 fs 接口的滞后。但这将随着节点 v13 的变化而改变。 php 也有数据兼容版本。【参考方案6】:

您可以将 JSON 数据保存在一个简单的文本文件中,然后在服务器重新启动时读取它。

const data = require("yourarrayfile.json");

然后像往常一样使用它。

【讨论】:

那会完成什么?文件的内容将丢失 - 它不会分配给任何变量。查看其他答案... 我提到你会先写文件(但没有指定如何),然后在服务器重新启动时读取它。所以基本上你的答案是什么。我只是用一种非常糟糕的方式写了我的:)【参考方案7】:

试试LowDB

Lowdb 是一个由 Lodash 提供支持的小型本地 JSON 数据库(支持 Node、Electron 和浏览器)。如果您了解 Lodash,那么您已经知道如何使用 Lowdb。

【讨论】:

【参考方案8】:

虽然 LokiJS 和 NeDB 看起来都有更多的用户,但我只是遇到了TaffyDB。虽然我自己没有尝试过,但我想我应该在这里添加它以保持完整性。

【讨论】:

【参考方案9】:

建议节点的 fs 系统的用户我必须同意。如果 mongoDB 等已经过大,其他人都在建议对我来说似乎总体上的东西。简单的语言环境存储或节点的 fs 库。

我记得当我开始我的 Web 开发之旅时,我对通过 mongoDB 等学习持久数据存储技术的了解还不够。但是 node 的 fs 库对我早期的一些应用程序起了作用。即使重新启动本地服务器,所有数据也保持不变

【讨论】:

以上是关于在 Node.js 下存储 JSON 的简单方法的主要内容,如果未能解决你的问题,请参考以下文章

node.js核心技术

NodeJS 存储基于文件的 JSON 数据库的最佳方式?

如何在 Node.js 中发现 JavaScript 内存漏洞

一种简单的生产环境部署Node.js程序方法

Node.js学习笔记七使用package.json

从 Node.js 将 Json 存储到 MySQL 数据库中