不过,我想知道我原来的语法有什么问题。
你原来的语法(基本上正确)使用argument mode https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parsing,其中参数,粗略地说,评估如下:
- 不以任何一个开头的争论
$
, (
, or @
被视为string,即使没有引用;尤其,[
is not这些特殊字符之中。
所以,[System.Text.Encoding]::UTF8
被解释为字符串字面量而不是作为返回一个的表达式System.Text.Encoding
实例,并且没有System.IO.StreamWriter
第三个参数是 a 的构造函数string可以被找寻到。
- 不幸的是,错误消息只提到了count的参数,而不表明不正确type可能是原因;这是一个已知问题 - 请参阅GitHub 问题 #3658 https://github.com/PowerShell/PowerShell/issues/3658.
正确的解决方案,正如评论中提到的PetSerAl https://stackoverflow.com/users/4003407/petseral, is to enclose [System.Text.Encoding]::UTF8
in (...)
从而迫使其评估表达 mode,它会产生所需的结果。
请注意,上述内容还意味着"..."
(双引号)周围a.txt
不是必要的(但不会造成伤害),所以我们得到:
Note: For brevity, I've omitted the initial System.
components from the full types in the following sample commands; e.g., IO.StreamWriter
refers to System.IO.StreamWriter
. Specifying the System.
part is optional in PowerShell in most contexts.
$f = New-Object IO.StreamWriter a.txt, $false, ([Text.Encoding]::UTF8)
注意它是,
在各个构造函数参数之间,导致它们作为array- 即,一个单一参数 - to New-Object https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/new-object,它(在位置上)绑定到数组类型-ArgumentList
(-Args
) 范围。
顺便说一句:将各个参数按位置传递给separate参数比较常见,需要spaces将他们分开;例如。,Select-String foo t.txt
被解析为
Select-String -Pattern foo -Path t.txt
.
您自己的答案(已删除)使用pseudo方法语法那是最好避免并且只有happens上班:
# AVOID: pseudo method syntax.
$f = New-Object IO.StreamWriter("a.txt", $false, [Text.Encoding]::UTF8)
尽管这looks就像方法调用(构造函数调用)一样,它不是,实际上解析如下:
$f = New-Object IO.StreamWriter -ArgumentList ("a.txt", $false, [Text.Encoding]::UTF8)
那是,您已将原始参数数组括在(...)
,这会导致其元素被解析为表达 mode, 包括[Text.Encoding]::UTF8
,这正好解决了你的问题。
请注意 - 与参数模式不同 - 字符串a.txt
does必须包含在"..."
(or '...'
) 在表达模式下。
作为旁白:
-
Set-StrictMode https://learn.microsoft.com/powershell/module/microsoft.powershell.core/set-strictmode
-Version 2
或更高,除其他外,prevents使用伪方法语法,但是only(一)对于两个或更多参数和 (b) 仅当参数列表 ((...)
)遵循命令名称(而不是argument,如在New-Object
情况),并且(c)仅当有no space命令名和开头之间(
; e.g.:
& { Set-Strictmode -version 2; foo('a', 'b') }
注意PSv5+ does提供一个method基于方法来构造对象,通过static new()
method裸露关于类型信息对象, 在这种情况下所有参数均在中解析表达 mode:
# PowerShell version 5 and above; you can use the ::new() method on types.
$f = [IO.StreamWriter]::new("a.txt", $false, [Text.Encoding]::UTF8)
注释when [System.Text.Encoding]::UTF8
需要:
与 Window PowerShell 不同,.NET默认为UTF-8(PowerShell [Core] (v6+) 现在也支持)。
-
当你read数据,因此通常不需要请求 UTF-8 编码明确地.
-
当你write data, passing [System.Text.Encoding]::UTF8
结果生成 UTF-8 文件with a BOM https://en.wikipedia.org/wiki/Byte_order_mark,同时依赖于defaultUTF-8编码创建文件withoutBOM(更有利于跨平台互操作性);要显式请求无 BOM 编码,请使用[System.Text.Utf8Encoding]::new()
.