将 nodejs 程序的输出重定向到文件时编码错误(windows 10 powershell 可能的问题)

Bad Encoding when redirecting output of nodejs program to file (windows 10 powershell possible issue)

我有一个简单的 javascript 文件(我们称它为 index.js),其中包含以下内容:

console.log('pérola');

我在 windows 10 上使用 VSCode 并且它使用 powershell 作为终端,当我使用以下命令执行文件时:

node index.js

我得到以下输出:

pérola

如果我运行以下:

node index.js > output.txt

我在文件中得到以下内容:

p├®rola

写入文件时,powershell 的编码似乎存在一些问题,当我在 VSCode 上打开文件时,我可以在右下角看到编码是 UTF-16 LE。

我也已经尝试过以下方法:

node index.js | out-file -encoding utf8 output.txt

文件保存为带有 BOM 的 UTF8,但编码仍然错误,因为我看到的是 p├®rola 而不是 pérola

谁能解释一下这里出了什么问题? 谢谢。

node 输出的内容是 UTF-8 编码的。

PowerShell 的 > 运算符 不会 将底层字节传递到输出文件。
相反,PowerShell 根据 [Console]::OutputEncoding 中存储的编码将 node 输出的字节转换为 .NET 字符串 ,然后根据 [Console]::OutputEncoding 隐含的编码保存生成的字符串> 运算符,实际上,从技术上讲,它是 Out-File cmdlet 的别名。

换句话说:为了让 PowerShell 正确解释 node 的输出,您必须(暂时)将 [Console]::OutputEncoding 设置为 [System.Text.Utf8Encoding]::new()

此外,您必须通过使用 Out-File -Encoding 或 - 最好是,如果输入已经是 text 来决定你希望输出文件具有什么字符编码 - Set-Content -Encoding 而不是 >.
也就是说,您需要这样做,除非 > / Out-Filedefault 字符编码适合您:它是“Unicode”(UTF16-LE) Windows PowerShell,以及 PowerShell [Core] v6+.

中的 BOM-less UTF-8

另请参阅:

  • 获取有关如何使 PowerShell 控制台 windows 始终如一地使用 UTF-8 的背景信息与外部程序通信[1],发送数据外部程序($OutputEncoding)和解释时数据 来自 外部程序 ([Console]::OutputEncoding):

    • 简而言之,将以下语句放入您的 $PROFILE:

      $OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
      
    • 如果您 运行 在 - obsolescent - Windows PowerShell ISE, you need an additional command to ensure that the ISE first allocates a hidden console behind the scenes; note that in the recommended replacement, Visual Studio Code with its PowerShell extension 中,则 不需要

      $null = chcp # Run any console application to force the ISE to create a console.
      $OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
      
  • 用于 system-wide 使 non-Unicode(控制台)应用程序使用 UTF-8 的方法,可用在 Windows 10 的最新版本中。这使得 cmd.exe 和 PowerShell 默认都使用 UTF-8。[1]

    • 警告:此功能仍处于 Windows 10 20H2 的 Beta 版,它可能会产生不必要的副作用 - 请参阅链接的答案。

[1]PowerShell自带的cmdlet使用的编码是受此控制; PowerShell cmdlet 有自己的默认值,不幸的是,这些默认值在 Windows PowerShell 中不一致,而在 PowerShell [Core] v6+ (BOM-less) 中 UTF-8 是一致的默认值;见 .