有没有办法强制Node使用Unicode字符的代理对(用JSON)编写文件?

时间:2017-05-19 19:34:46

标签: javascript json unicode utf-8

根据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,以便正在编写的文件,但没有任何更改。

有没有办法强制使用代理对?

1 个答案:

答案 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为单位)。

如果这不是目标,那么至少有一个小问题没有问题。