mbe*_*ger 3 powershell encoding ascii
我正在尝试生成每个 ASCII 字符 1 个的字符串。我开始于
32..255| %{[char]$_ | Out-File -filepath .\outfile.txt -Encoding ASCII -Append}
Run Code Online (Sandbox Code Playgroud)
我期望的是可打印字符列表,但我得到了不同的字符。
谁能向我指出获得预期结果的更好方法,或者解释为什么我会得到这些结果?
[char[]] (32..255) | Set-Content outfile.txt
Run Code Online (Sandbox Code Playgroud)
在Windows PowerShell中,这将创建一个“ANSI”编码的文件。术语“ANSI”编码是Windows 上一组固定宽度、单字节、8 位编码的总称,它是ASCII编码的超集。使用的特定“ANSI”编码是由与系统上有效的旧系统区域设置关联的代码页暗示的[1];例如,美式英语系统上的Windows-1252 。
请参阅底部部分了解为什么应避免“ANSI”编码。
如果您要在PowerShell (Core) 7+中执行相同的操作,您将获得一个没有BOM 的UTF-8编码文件,这是用于跨平台和跨区域设置兼容性的最佳编码。
在 Windows PowerShell 中,添加-Encoding utf8也会为您提供一个 UTF-8 文件,但带有BOM。[2]
如果您使用-Encoding Unicode或仅使用重定向运算符>或Out-File,您将获得一个UTF-16LE编码的文件。
(相比之下,在PowerShell (Core)中,>默认情况下会生成无 BOM 的 UTF-8,因为后者是一致应用的默认编码)。
注意:对于字符串和数字,Set-Content和>/Out-File可以互换使用(Windows PowerShell 中的编码差异除外);对于其他类型,仅>/Out-File产生有意义的表示,尽管仅适合人眼,而不适合编程处理 -有关更多信息,请参阅此答案。
ASCII 代码点仅限于 7 位值,即范围0x0- 0x7f( 127)。
因此,您的输入值128无法255表示为 ASCII 字符,并且使用会导致-Encoding ASCII无效的输入字符被替换为文字 ?字符(代码点0x3f/ 63),从而导致信息丢失。
重要的:
在内存中,32将(0x20) 或255(等数字转换0xFF为[char](System.Char) 实例会导致数字被解释为UTF-16代码单元,表示 Unicode 字符[3],例如U+0020和U+00FF使用本机字节顺序的 2 字节序列,因为这就是 .NET 中的字符。
类似地,.NET[string]类型System.String是一个或多个[char]实例的序列。
在输出到文件时或在序列化期间,可能会对这些 UTF-16 字符串进行重新编码,具体取决于隐含或指定的输出编码。
如果输出编码是固定的单字节编码,例如ASCII,Default(“ANSI”)或OEM,则可能会发生信息丢失,即如果要输出的字符串包含无法用目标编码表示的字符。
选择一种基于Unicode的编码格式可以保证:
Unicode)是内存中代码单元的直接表示,但请注意,每个字符都使用(至少) 2 个字节进行编码,这导致字符串的大小最多为 UTF-8 文件大小的两倍主要包含 ASCII 范围内的字符。bigendianunicode)会反转每个代码单元中的字节顺序。UTF32)将每个 Unicode 字符表示为固定的 4 字节序列;与 UTF-16 相比,这通常会导致文件过大。[1] 在 Windows 支持的旧版代码页中,还有固定双字节和可变宽度编码,但仅适用于东亚语言环境;有时它们(错误地)统称为DBCS(双字节字符集),而不是 SBCS(单字节字符集);查看所有 Windows 代码页的列表。
[2] 请参阅此答案,了解如何在 Windows PowerShell 中创建无 BOM 的UTF-8 文件。
[3] 严格来说,UTF-16 代码单元标识一个 Unicode 代码点,但并非每个代码点本身都是完整的 Unicode 字符,因为某些(罕见的)Unicode 字符的代码点值超出了可识别的范围。可以用 16 位整数表示,并且这些代码点也可以用2 个其他代码点的序列(称为代理对)表示。