【问题标题】:List of encodings that Node.js supportsNode.js 支持的编码列表
【发布时间】:2013-01-11 04:13:29
【问题描述】:

我需要读取一个用 ISO-8859-1(也称为 latin1)编码的文件,如下所示:

var file_contents = fs.readFileSync("test_data.html", "latin1");

但是,Node 抱怨“latin1”或“ISO-8859-1”不是有效编码(“错误:未知编码”)。

readFileSync 接受哪些编码?

【问题讨论】:

标签: node.js


【解决方案1】:

node原生支持的list of encodings比较短:

  • ascii
  • base64
  • 十六进制
  • ucs2/ucs-2/utf16le/utf-16le
  • utf8/utf-8
  • binary/latin1(ISO8859-1,latin1 仅在节点 6.4.0+ 中)

如果您使用的是 6.4.0 之前的版本,或者不想处理非 Unicode 编码,您可以重新编码字符串:

使用iconv-lite 重新编码文件:

var iconvlite = require('iconv-lite');
var fs = require('fs');

function readFileSync_encoding(filename, encoding) {
    var content = fs.readFileSync(filename);
    return iconvlite.decode(content, encoding);
}

或者,使用iconv:

var Iconv = require('iconv').Iconv;
var fs = require('fs');

function readFileSync_encoding(filename, encoding) {
    var content = fs.readFileSync(filename);
    var iconv = new Iconv(encoding, 'UTF-8');
    var buffer = iconv.convert(content);
    return buffer.toString('utf8');
}

【讨论】:

  • 对于那些在编译 iconv 时遇到问题的人,我推荐iconv-lite。它不需要编译,根据 dev 比 iconv 更快,它被 Grunt、Nodemailer、Yeoman 等流行工具使用...
  • 您在答案中所说的——不支持 ISO-8859-1(又名latin1)——不适用于 Node v8.1.4。参见this documentation page,查看Buffer支持的所有编码,包括latin1(别名为binary)。
  • 我觉得奇怪的是,根据nodejs.org/api/… encoding-names 'latin1' 和 'binary' 的意思是一样的。为什么会这样?我对此有所了解,因为我认为“二进制”与“无编码”的含义相同
  • @PanuLogic 从字节串转换为字符串时,需要some 编码。 latin1 是可逆的——即使您的输入是一个 mp4 视频文件,该字符串也是有效的(尽管没有意义),并且转换回字节将产生原始字节。对二进制数据使用Buffer/Uint8Array
  • @PanuLogic 如果您在未指定编码的情况下编写,则字符串将被编写为 UTF-8。因此,以 latin1 格式读取并在没有编码的情况下写入是安全的;这将创建mojibake。相反,使用{encoding: null} 阅读(或不指定编码)。这样,您将获得一个缓冲区。缓冲区已经是二进制数据,因此在写入 encoding 参数时,它们会被忽略。
【解决方案2】:

如果上述解决方案对您不起作用,则可以使用以下纯 nodejs 代码获得相同的结果。以上对我不起作用,并在 OSX 上运行“npm install iconv”时导致编译异常:

npm install iconv

npm WARN package.json portalServer@0.1.0 No README.md file found!
npm http GET https://registry.npmjs.org/iconv
npm http 200 https://registry.npmjs.org/iconv
npm http GET https://registry.npmjs.org/iconv/-/iconv-2.0.4.tgz
npm http 200 https://registry.npmjs.org/iconv/-/iconv-2.0.4.tgz

> iconv@2.0.4 install /Users/markboyd/git/portal/app/node_modules/iconv
> node-gyp rebuild

gyp http GET http://nodejs.org/dist/v0.10.1/node-v0.10.1.tar.gz
gyp http 200 http://nodejs.org/dist/v0.10.1/node-v0.10.1.tar.gz
xcode-select: Error: No Xcode is selected. Use xcode-select -switch <path-to-xcode>, or see the xcode-select manpage (man xcode-select) for further information.

如果没有指定编码,fs.readFileSync() 返回一个 Buffer。并且 Buffer 有一个 toString() 方法,如果没有指定编码给你文件的内容,它将转换为 UTF8。请参阅 nodejs 文档。这对我有用。

【讨论】:

  • 问题是缓冲区假设数据已经在 utf8 中,如果没有指定,并且不会尝试从 latin1 转换为 utf8。
【解决方案3】:

编码在buffer documentation 中详细说明。

Buffers and character encodings:

字符编码

  • utf8:多字节编码的 Unicode 字符。许多网页和其他文档格式使用 UTF-8。这是默认的字符编码。
  • utf16le:多字节编码的 Unicode 字符。与 utf8 不同,字符串中的每个字符都将使用 2 或 4 个字节进行编码。
  • latin1:Latin-1 代表 ISO-8859-1。此字符编码仅支持从U+0000U+00FF 的Unicode 字符。

二进制转文本编码

  • base64:Base64 编码。从字符串创建缓冲区时,此编码还将正确接受 RFC 4648 第 5 节中指定的“URL 和文件名安全字母”。
  • hex:将每个字节编码为两个十六进制字符。

传统字符编码

  • ascii:仅适用于 7 位 ASCII 数据。通常,没有理由使用这种编码,因为在编码或解码纯 ASCII 文本时,“utf8”(或者,如果已知数据始终是 ASCII-only,则“latin1”)将是更好的选择。
  • binary:“latin1”的别名。
  • ucs2:“utf16le”的别名。

【讨论】:

    猜你喜欢
    • 2012-02-02
    • 2011-10-03
    • 2014-02-10
    • 2014-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2011-02-11
    相关资源
    最近更新 更多