根据this question JSON是使用代理对自动编写的。
然而,这不是我的经验。
使用节点6.9.2
和以下代码,我的文件仍显示未使用代理项对编码的字符。
const fs = require('fs')
const infile = fs.readFile('raw.json', 'utf8', (err, data) => {
if (err) {
throw err
}
data = JSON.stringify(data)
fs.writeFile('final.json', data, 'utf8', (err) => {
if (err) {
throw err
}
console.log('done')
})
})
在我的编辑器中,必须具有良好的unicode和use以及具有这些字符的字形的字体,文件raw.json
的内容包含"題"
该字符仍显示在final.json
中(未进行任何更改)。
此外,我尝试将编码utf8
切换为utf16le
,以便正在编写的文件,但没有任何更改。
有没有办法强制使用代理对?
答案 0 :(得分:5)
如果有人断定JSON.stringify
会将基本多语言平面之外的字符串中的Unicode字符转换为\u
转义的代理对价值序列,则引用的问题会产生误导。 This answer更好地解释了JSON.stringify
如何只需要反斜杠(\
),双引号("
)和控制字符。
因此,如果输入数据包含占用多个八位字节的字符(例如,例如“'''),它将作为该字符写入输出文件。如果成功写入文件然后使用UTF16编码回读,则希望UTF8编码的输入字符是您看到的字符。
如果目标是使用非{ASCII}值的\u
转义字符和BMP之外的字符的代理对将JSON文本转换为ASCII,则可以使用简单字符检查处理JSON格式的字符串(JSON具有已经转换了引号,反斜杠和控制字符:
var jsonComponent = '"2®π≤題"'; // for example
function jsonToAscii( jsonText) {
var s = "";
for( var i = 0; i < jsonText.length; ++i) {
var c = jsonText[ i];
if( c >= '\x7F') {
c = c.charCodeAt(0).toString(16);
switch( c.length) {
case 2: c = "\\u00" + c; break;
case 3: c = "\\u0" + c; break;
default: c = "\\u" + c; break;
}
}
s += c;
}
return s;
}
console.log( jsonToAscii( jsonComponent));
这利用了JavaScript字符串已经在UTF16中的事实(因此包含代理项对),但是通过数组符号查找和.charAt
方法作为连续的UCS-2 16位值进行访问。请注意,'题'不在BMP之外,只需要UTF16中的两个八位字节,而表情符号在平面0之外,需要4个八位字节(以UTF16为单位)。
如果这不是目标,那么至少有一个小问题没有问题。