DB.js调用write(null)生成{null}区块问题及修复需求
解决无区块键存储的{null}问题及顺序问题
问题根源
- 对象键类型限制:JavaScript对象的键仅支持字符串/Symbol,传入
null/undefined作为partName时,会被自动转为字符串'null'/'undefined',原代码的part !== null判断无法识别该情况,导致错误输出{null}区块。 - 加载逻辑缺陷:原
_loadDataFromFile方法会忽略文件中无区块的键,导致这类键无法被正确加载到内存。 - 顺序不可控:原代码按对象键的遍历顺序输出内容,无法保证无区块键处于文件顶部。
修改后的完整DB.js代码
import fs from 'fs'; class DB { constructor(filePath) { this.filePath = filePath; this.data = this._loadDataFromFile(); } _loadDataFromFile() { try { const data = fs.readFileSync(this.filePath, 'utf8'); const entries = data.split(/\r?\n/); const parsedData = { __headerless__: {} }; let currentPart = null; for (const entry of entries) { const trimmedEntry = entry.trim(); if (!trimmedEntry) continue; if (trimmedEntry.startsWith('{')) { currentPart = trimmedEntry.slice(1, -1).trim(); if (!parsedData[currentPart]) { parsedData[currentPart] = {}; } } else if (trimmedEntry.includes('=')) { const [key, ...valueParts] = trimmedEntry.split('='); const keyTrimmed = key.trim(); const value = valueParts.join('=').trim(); if (!keyTrimmed) continue; if (currentPart === null) { parsedData.__headerless__[keyTrimmed] = value; } else if (parsedData[currentPart]) { parsedData[currentPart][keyTrimmed] = value; } } } if (Object.keys(parsedData.__headerless__).length === 0) { delete parsedData.__headerless__; } return parsedData; } catch (error) { return { __headerless__: {} }; } } _saveDataToFile() { let dataStr = ''; // 优先输出无区块的键,保证在文件顶部 if (this.data.__headerless__) { for (const key in this.data.__headerless__) { dataStr += `${key}=${this.data.__headerless__[key]}\n`; } } // 输出各个区块内容 for (const part in this.data) { if (part === '__headerless__') continue; dataStr += `{${part}}\n`; for (const key in this.data[part]) { dataStr += `${key}=${this.data[part][key]}\n`; } } // 移除末尾多余的换行符 if (dataStr.endsWith('\n')) { dataStr = dataStr.slice(0, -1); } fs.writeFileSync(this.filePath, dataStr, 'utf8'); } read(partName, keyName) { if (partName == null) { return this.data.__headerless__?.[keyName]; } return this.data[partName]?.[keyName]; } write(partName, keyName, value) { const targetPart = (partName == null) ? '__headerless__' : partName; if (!this.data[targetPart]) { this.data[targetPart] = {}; } this.data[targetPart][keyName] = value; this._saveDataToFile(); return value; } } export default DB;
关键修改点
- 新增特殊存储字段:用
__headerless__专门存储无区块的键,避免与普通区块混淆。 - 修复加载逻辑:正确识别并加载文件中无区块的键到
__headerless__。 - 优化写入逻辑:自动将
null/undefined的partName映射到__headerless__,并优先输出该字段的内容。 - 兼容特殊场景:支持值中包含
=的情况,跳过空行避免无效内容。
内容的提问来源于stack exchange,提问作者partialinvisibility
相关产品推荐
相关产品推荐

