NODE.JS 如何在不填满存储空间的情况下保存 JSON 数据 [关闭]
Posted
技术标签:
【中文标题】NODE.JS 如何在不填满存储空间的情况下保存 JSON 数据 [关闭]【英文标题】:NODE.JS How do I save JSON data without filling up my storage [closed] 【发布时间】:2021-08-07 17:27:21 【问题描述】:标题确实说明了这一点。
我制作了一个不和谐机器人,并添加了一个排名系统,该系统在我的文件系统中存储了它的内存。但是,如果加入的人太多,我的存储空间就会被填满。也许我有办法访问 node.js 服务器?也许本地主机?我只想要免费保存数据的任何东西,不由我以外的任何人管理,并且不占用我的存储空间。
【问题讨论】:
您能否扩展一下您正在做的事情并为您的问题提供更多背景信息?目前,这个问题听起来有点像XY problem。也许您正在寻找database。 idownvotedbecau.se/unclearquestion 所以只需在本地机器上运行任何数据库) @NikitaMazur 任何在 OP 机器上运行的数据库也会耗尽它们宝贵的有限存储空间。 @MrMythical 是的,您只需让机器人写入该驱动器上的文件(或设置使用该驱动器作为存储的数据库)。快速测试意味着 10 000 个用户将占用您的架构将占用大约 700 KB 的磁盘空间,即每个用户大约 70 个字节。使用 399 GB,您可以存储大约 5 700 000 000 个用户。 【参考方案1】:配置
对于这个答案,我们将建立一个简单的 config
对象来存储任何值 -
// config.json
"counter":0
服务器
我们将使用http.createServer 创建一个简单的服务器。我们将使用请求方法和请求 URL 来查找 handler
或在未找到处理程序时以 404 响应 -
// server.js
import createServer from "http"
import readFile, writeFile from "fs/promises"
const server = createServer(async (req, res) =>
const handler = routes?.[req.method.toLowerCase()]?.[req.url]
if (handler == null)
res.writeHead(404, 'Content-Type': 'text/plain')
res.end(`No route for $req.method $req.url`)
else
await handler(req, res)
res.end()
)
server.listen(8000)
接下来我们将routes
定义为/getConfig
和/saveConfig
-
// server.js (continued)
const routes =
get:
"/getConfig": async (req, res) =>
res.writeHead(200, 'content-type': 'application/json')
res.write(await readFile("./config.json"))
,
post:
"/saveConfig": async (req, res) =>
await writeFile("./config.json", await readBody(req))
res.writeHead(204)
,
"/reset": async (req, res) =>
await writeFile("./config.json", JSON.stringify( counter: 0 ))
res.writeHead(204)
这取决于一个可重用的助手,readBody
-
// server.js (continued)
function readBody(req)
return new Promise((resolve, reject) =>
const body = []
req.on('data', chunk => body.push(Buffer.from(chunk)))
req.on('end', _ => resolve(Buffer.concat(body).toString()))
req.on('error', reject)
)
客户
在这种情况下,您的机器人是 http 客户端。 http.get 的节点文档包含这个冗长的示例,但不要让您担心 -
// example from node docs
http.get('http://localhost:8000/', (res) =>
const statusCode = res;
const contentType = res.headers['content-type'];
let error;
// Any 2xx status code signals a successful response but
// here we're only checking for 200.
if (statusCode !== 200)
error = new Error('Request Failed.\n' +
`Status Code: $statusCode`);
else if (!/^application\/json/.test(contentType))
error = new Error('Invalid content-type.\n' +
`Expected application/json but received $contentType`);
if (error)
console.error(error.message);
// Consume response data to free up memory
res.resume();
return;
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => rawData += chunk; );
res.on('end', () =>
try
const parsedData = JSON.parse(rawData);
console.log(parsedData);
catch (e)
console.error(e.message);
);
).on('error', (e) =>
console.error(`Got error: $e.message`);
);
您不应逐字复制此内容。想象一下,每次您想获取一些 JSON 时都要编写那么多代码。您可以将http 模块视为一个低级 API,使您能够设计更高级别的函数 -
// client.js
import * as http from "http"
function request (href, body = "", ...options = )
return new Promise((resolve, reject) =>
http.request(href, options, res =>
const data = []
res.on('data', chunk => data.push(chunk))
res.on('end', _ => resolve(
status: res.statusCode,
headers: res.headers,
data: Buffer.concat(data).toString()
))
)
.on('error', reject)
.end(body)
)
在我们的request
函数之上解析一个 status, headers, data
对象,我们可以编写专门的表单get
和getJson
,使其更容易与 -
// client.js (continued)
async function get (href)
const status, headers, data = await request(href)
if (status < 200 || status >= 300)
throw Error(status)
return status, headers, data
async function getJson (href)
const headers, data = await get(href)
if (!headers['content-type'].startsWith("application/json"))
throw Error(`expected application/json but received $headers['content-type']`)
return JSON.parse(data)
我们可以为post
做同样的事情-
// client.js (continued)
async function post (href, body = "")
const status, headers, data = await request(href, body, method: "POST" )
if (status < 200 || status >= 300)
throw Error(status)
return status, headers, data
最后是我们的bot
代码。它通过get
读取配置,通过post
更新配置,并通过get
重新读取配置返回确认结果-
// client.js (continued)
async function bot()
const config = await getJson("http://localhost:8000/getConfig")
await post("http://localhost:8000/saveConfig", JSON.stringify(counter: config.counter + 1))
return getJson("http://localhost:8000/getConfig")
bot().then(console.log, console.error)
运行
在终端中启动server
-
$ node ./server.js
在单独的终端中,运行几次client
-
$ node ./client.js
counter: 1
$ node ./client.js
counter: 2
$ node ./client.js
counter: 3
节点模块
在上面,我们采取了一种 DIY 方法来解决这个问题。但是这种问题之前已经解决了很多方法。有一些流行的库,如 express 和 koajs,这将使这一切变得容易得多。既然您知道它们的用途,那就试试吧!
【讨论】:
【参考方案2】:只需使用数据库,mongoDB atlas 就可以很好地满足您的需求,因为它是基于云的并且非常易于设置。您可以按照此tutorial 将您的 discord 机器人与 mongoDB atlas 连接起来。
【讨论】:
以上是关于NODE.JS 如何在不填满存储空间的情况下保存 JSON 数据 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Node.js:如何在不上传文件列表的情况下检查文件夹是不是为空
如何在不重新加载页面的情况下将任意 JSON 发送到 node.js?
是否可以在不调用“节点”的情况下运行 Node.js 脚本?