为什么当我使用 fs.readFileSync() 在 Node.js 上使用不同的编码时输出相同?
Why is the output the same when I use different encodings on Node.js using fs.readFileSync()?
我试图理解为什么当我使用 readFileSync 方法并使用不同的编码(例如 utf-8、十六进制、ascii)时,我在控制台上有相同的输出,而当我没有传递任何特定的编码时,我收到utf-8 格式的输出。
我的意思是,如果我不指定任何编码并接收有关 utf-8 格式的信息,我不应该收到有关文件格式的信息(在本例中为 .sol)如果我指定 utf-8格式?
我觉得有些地方我不理解收尾的工作原理。
const path = require('path');
const fs = require('fs');
const solc = require('solc')
const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxPath, 'utf8');
console.log(solc.compile(source, 1));
当你这样称呼它时:
const source = fs.readFileSync(inboxPath, 'utf8');
您正在将 utf8 编码传递给函数。它将从文件中读取数据并将编码应用于数据以将其转换为字符串。
如果你这样调用它没有编码:
console.log(solc.compile(source, 1));
它将为您提供 Buffer 对象中的原始二进制数据,您将得到如下内容(如果您 console.log(source)
):
<Buffer 54 65 73 74 69 6e 67 20 4e 6f 64 65 2e 6a 73 20 72 65 61 64 46 69 6c 65 28 29>
缓冲区数据的显示是为二进制数据的每 8 位显示一个十六进制值(为了我们的查看方便)。缓冲区开头的 54
对应于字母 T
因此,如果您将该缓冲区转换为具有 utf8
或 ascii
编码的字符串,您将得到以 T
.
开头的字符串
如果您的数据全部由字符代码小于 128 的字符组成,则使用 utf8 和 ascii 编码对其进行解释会得到相同的结果。这是因为对于编码小于 128 的字符,utf8 只是直接使用该字符的编码。只有当字符代码高于 128 时,utf8 才开始使用超过一个字节的字符(实际上,它可以使用 1-4 个字节,具体取决于实际代码)。 unicode 中有 1,112,064 个代码点。由于您只能在一个字节中表示 256 个唯一值,因此显然需要一个以上的字节来表示 unicode 中的所有 1,112,064 个代码点。当使用 utf8 时,这是一种可变长度编码,对于代码小于 128 的任何内容,每个字符使用一个字节,一旦超过 128,它就会开始对这些字符使用多个字节。
你的函数在这里调用:
console.log(solc.compile(source, 1));
显然在 source
参数中需要一个字符串,所以你必须给它一个字符串。如果你不传递这样的编码:
const source = fs.readFileSync(inboxPath, 'utf8');
那么,source
是一个 Buffer 对象(不是字符串),而 solc.compile(source, 1)
函数不喜欢那样并给你一个错误。您显然需要向该函数传递一个字符串。因此,您在问题中显示的代码:
const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxPath, 'utf8');
console.log(solc.compile(source, 1));
正确地从 fs.readFileSync()
获取字符串,然后将该字符串传递给 solc.compile()
。
我试图理解为什么当我使用 readFileSync 方法并使用不同的编码(例如 utf-8、十六进制、ascii)时,我在控制台上有相同的输出,而当我没有传递任何特定的编码时,我收到utf-8 格式的输出。
我的意思是,如果我不指定任何编码并接收有关 utf-8 格式的信息,我不应该收到有关文件格式的信息(在本例中为 .sol)如果我指定 utf-8格式?
我觉得有些地方我不理解收尾的工作原理。
const path = require('path');
const fs = require('fs');
const solc = require('solc')
const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxPath, 'utf8');
console.log(solc.compile(source, 1));
当你这样称呼它时:
const source = fs.readFileSync(inboxPath, 'utf8');
您正在将 utf8 编码传递给函数。它将从文件中读取数据并将编码应用于数据以将其转换为字符串。
如果你这样调用它没有编码:
console.log(solc.compile(source, 1));
它将为您提供 Buffer 对象中的原始二进制数据,您将得到如下内容(如果您 console.log(source)
):
<Buffer 54 65 73 74 69 6e 67 20 4e 6f 64 65 2e 6a 73 20 72 65 61 64 46 69 6c 65 28 29>
缓冲区数据的显示是为二进制数据的每 8 位显示一个十六进制值(为了我们的查看方便)。缓冲区开头的 54
对应于字母 T
因此,如果您将该缓冲区转换为具有 utf8
或 ascii
编码的字符串,您将得到以 T
.
如果您的数据全部由字符代码小于 128 的字符组成,则使用 utf8 和 ascii 编码对其进行解释会得到相同的结果。这是因为对于编码小于 128 的字符,utf8 只是直接使用该字符的编码。只有当字符代码高于 128 时,utf8 才开始使用超过一个字节的字符(实际上,它可以使用 1-4 个字节,具体取决于实际代码)。 unicode 中有 1,112,064 个代码点。由于您只能在一个字节中表示 256 个唯一值,因此显然需要一个以上的字节来表示 unicode 中的所有 1,112,064 个代码点。当使用 utf8 时,这是一种可变长度编码,对于代码小于 128 的任何内容,每个字符使用一个字节,一旦超过 128,它就会开始对这些字符使用多个字节。
你的函数在这里调用:
console.log(solc.compile(source, 1));
显然在 source
参数中需要一个字符串,所以你必须给它一个字符串。如果你不传递这样的编码:
const source = fs.readFileSync(inboxPath, 'utf8');
那么,source
是一个 Buffer 对象(不是字符串),而 solc.compile(source, 1)
函数不喜欢那样并给你一个错误。您显然需要向该函数传递一个字符串。因此,您在问题中显示的代码:
const inboxPath = path.resolve(__dirname, 'contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxPath, 'utf8');
console.log(solc.compile(source, 1));
正确地从 fs.readFileSync()
获取字符串,然后将该字符串传递给 solc.compile()
。