Dan*_*ler 2 powershell encoding ascii utf-8
当我尝试使用 Powershell 操作 .ini 文件时,它总是将编码切换为 UTF-8。
我的代码:
Get-Content -Path "./update.ini" -Encoding ascii | Out-File -FilePath "ascii_update.ini" -Encoding ascii
Run Code Online (Sandbox Code Playgroud)
该文件需要保持 ASCII,那么如何禁用此行为或如何将其切换回 ASCII?
\n
\n\n德语字符将无法正确显示
\n
鉴于您不需要 UTF-8 编码但又想要德语元音变音,您要寻找的是ANSI编码,而不是ASCII。
\nGet-ContentSet-Content Out-File编码,因此您需要执行以下操作:# Windows PowerShell: ANSI encoding is the default for Get-Content / Set-Content\nGet-Content ./update.ini | Set-Content ascii_update.ini\nRun Code Online (Sandbox Code Playgroud)\n在PowerShell (Core) 7+中,(无 BOM)UTF-8 现在是所有cmdlet 的默认设置,因此您必须显式请求 ANSI 编码请求 ANSI 编码,使用-Encoding
$ansiEnc = [cultureinfo]::CurrentCulture.TextInfo.ANSICodePage\nGet-Content -Encoding $ansiEnc ./update.ini |\n Set-Content -Encoding $ansiEnc ascii_update.ini\nRun Code Online (Sandbox Code Playgroud)\n\n\n记事本在右下角将其显示为 UTF-8。
\n
ASCII 编码是一个子集,这就是为什么大多数编辑器将纯 ASCII 文件显示为 UTF-8,因为根据定义它们也是有效的 UTF-8 文件。
\n请注意,如果您使用 保存或读取包含非 ASCII 字符的文本-Encoding ASCII,非 ASCII 字符将“有损地”转码为逐字?字符。
zett42指出WritePrivateProfileString和GetPrivateProfileString\nWindows API 函数解释 INI 文件如下:
如果文件具有 UTF-16LE(“Unicode”)BOM,则会按此方式读取和更新。
\n否则,它总是被解释为 ANSI 编码(即使它具有不同的 Unicode 编码 BOM,例如 UTF-8)。
\n如果您隐式WritePrivateProfileString创建 INI 文件,则它始终会在没有BOM 的情况下创建,因此被视为 ANSI 编码(即使您使用 API 函数的 Unicode 版本)。如果您尝试将非 ANSI 范围的 Unicode 字符写入这样的文件,它们将被悄悄地、有损地转码如下:对于重音字母,如果适用的话,转码为 ASCII 范围的等效值(例如,转码为\xc4\x83a);否则,逐字逐句?
因此,必须使用UTF-16lE BOM显式创建感兴趣的 INI 文件,以便将文件维护为 UTF-16LE 编码,从而启用完整的 Unicode 支持。
\n因此,您可以最初使用诸如 之类的命令创建 INI 文件Set-Content -Encoding Unicode ./update.ini -Value @(),该命令创建一个仅包含 UTF-16LE BOM 的(否则)空文件,然后坚持使用-Encoding Unicode如果您需要直接操作该文件,则继续使用。
这个 MIT 许可的 Gist(由我创作)包含模块 file IniFileHelper.psm1,其Get-IniValue和Set-IniValue函数包装了上述 Windows API 函数,其关键区别在于当Set-IniValue 隐式创建 INI 文件时,它使用 UTF-16LE 编码。
下面的独立示例演示了这一点:
\n# Download the module code and import it via a session-scoped, dynamic module.\n# IMPORTANT: \n# While I can personally assure you that doing this is safe,\n# you should always check the source code yourself first.\n$null = New-Module -Verbose -ScriptBlock ([scriptblock]::Create((Invoke-RestMethod \'https://gist.githubusercontent.com/mklement0/006c2352ddae7bb05693be028240f5b6/raw/1e2520810213f76f2e8f419d0e48892a4009de6a/IniFileHelper.psm1\')))\n\n# Implicitly create file "test.ini" in the current directory,\n# and write key "TestKey" to section "Main", with a value\n# that contains an ASCII-range character, an ANSI-range character,\n# and a character beyond either of these two ranges.\nSet-IniValue test.ini Main TestKey \'ha\xc3\xa4\xc4\x83\'\n\n# Now retrieve the same entry, which should show the exact\n# same value, \'ha\xc3\xa4\xc4\x83\'\n# Note: If there is a preexisting "test.ini" file that does NOT\n# have a UTF-16LE BOM, the non-ANSI \'\xc4\x83\' character would be\n# "best-fit" transcoded to ASCII \'a\'.\n# Other non-ANSI characters that do not have ASCII-range analogs\n# would be lossily transcoded to verbatim \'?\'\nGet-IniValue test.ini Main TestKey\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
649 次 |
| 最近记录: |