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