如何在 Powershell 中使用编码创建 System.IO.StreamWriter? [英] How to create System.IO.StreamWriter with Encoding in Powershell?

查看:44
本文介绍了如何在 Powershell 中使用编码创建 System.IO.StreamWriter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 PowerShell 中使用 UTF8 编码创建 StreamWriter 的实例.

I'm trying to create instance of StreamWriter with UTF8 encoding in PowerShell.

$f = New-Object System.IO.StreamWriter "a.txt", $false, [System.Text.Encoding]::UTF8

这会引发错误:新对象:找不到StreamWriter"的重载和参数计数:3".

This throws error: New-Object : Cannot find an overload for "StreamWriter" and the argument count: "3".

我正在尝试调用这个构造函数:https://msdn.microsoft.com/en-us/library/f5f5x7kt(v=vs.110).aspx

I'm trying to invoke this constructor: https://msdn.microsoft.com/en-us/library/f5f5x7kt(v=vs.110).aspx

推荐答案

不过,我想知道我原来的语法有什么问题.

Still, I would like to know what is wrong with my original syntax.

您的原始语法(基本正确)使用 argument 模式,在这种模式下,松散地说,评估如下:

Your original syntax (fundamentally correctly) uses argument mode, in which arguments are, loosely speaking, evaluated as follows:

  • 不以$(@ 开头的参数被视为字符串,即使没有引用;值得注意的是,[不是在这些特殊字符中.
  • An argument that doesn't start with either $, (, or @ is treated as a string, even if not quoted; notably, [ is not among these special characters.

因此,[System.Text.Encoding]::UTF8 被解释为字符串文字,而不是返回一个表达式System.Text.Encoding 实例,并且找不到第三个参数是 stringSystem.IO.StreamWriter 构造函数.

Therefore, [System.Text.Encoding]::UTF8 is interpreted as a string literal rather than as an expression that returns an System.Text.Encoding instance, and no System.IO.StreamWriter constructor whose 3rd argument is a string can be found.

  • 不幸的是,错误消息只提到了参数的计数,而没有指出错误的类型可能是原因;这是一个已知问题 - 请参阅此 GitHub 问题.
  • Unfortunately, the error message only mentions the count of arguments, without indicating that an incorrect type might be the cause; this is a known problem - see this GitHub issue.

PetSerAl 的评论中所述,正确的解决方案是[System.Text.Encoding]::UTF8 in (...) 以强制其在表达式模式下求值,在那里它产生想要的结果.

The correct solution, as mentioned in a comment by PetSerAl, is to enclose [System.Text.Encoding]::UTF8 in (...) so as to force its evaluation in expression mode, where it yields the desired result.

请注意,上面还暗示 a.txt 周围的 "..."(双引号)不是必需的(但不会造成伤害),所以我们得到:

Note that the above also implies that the "..." (double quotes) around a.txt aren't necessary (but do no harm), so we get:

注意:为简洁起见,我在以下示例命令中省略了完整类型中的初始 System. 组件;例如,IO.StreamWriter 指的是 System.IO.StreamWriter.在大多数情况下,在 PowerShell 中指定 System. 部分是可选.

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)

请注意,正是各个构造函数参数之间的 , 导致它们作为数组被传递——即,一个单个参数 - 到 New-Object,它(位置)绑定到数组类型的 -ArgumentList (-Args) 参数.
顺便说一句:将单个参数按位置传递给 separate 参数更为常见,并且需要 空格 来分隔它们;例如,Select-String foo t.txt 被解析为
Select-String -Pattern foo -Path t.txt.

Note that it is the , between the individual constructor arguments that causes them to be passed as an array - i.e., a single argument - to New-Object, where it is (positionally) bound to the array-typed -ArgumentList (-Args) parameter.
As an aside: passing individual arguments positionally to separate parameters is more common, and requires spaces to separate them; e.g., Select-String foo t.txt is parsed as
Select-String -Pattern foo -Path t.txt.

您自己的答案(自删除后)使用方法语法,这是最好避免并且仅发生工作:

Your own answer (since deleted) uses pseudo method syntax that is best avoided and only happens to work:

# AVOID: pseudo method syntax.
$f = New-Object IO.StreamWriter("a.txt", $false, [Text.Encoding]::UTF8)

尽管这看起来像一个方法调用(构造函数调用),但它不是,实际上解析如下:

Even though this looks like a method call (constructor call), it isn't, and is actually parsed as follows:

$f = New-Object IO.StreamWriter -ArgumentList ("a.txt", $false, [Text.Encoding]::UTF8)

也就是说,您已将原始参数数组包含在 (...) 中,这会导致其元素以表达式 模式进行解析strong>,包括 [Text.Encoding]::UTF8,正好解决了您的问题.

That is, you've enclosed the original argument array in (...), which causes its elements to be parsed in expression mode, including [Text.Encoding]::UTF8, which happened to solve your problem.

请注意 - 与参数模式不同 - 字符串 a.txt 确实 必须包含在 "..." (或 '...') 在表达式模式中.

Note that - unlike in argument mode - string a.txt does have to be enclosed in "..." (or '...') in expression mode.

请注意,PSv5+ 确实提供了一种基于方法的方法来构造对象,通过静态new() 方法暴露类型信息对象,在这种情况下所有参数都在表达式模式下解析::>

Note that PSv5+ does offer a method-based way to construct objects, via the static new() method exposed on type-information objects, in which case all arguments are parsed in expression mode:

# PowerShell version 5 and above; you can use the ::new() method on types.
$f = [IO.StreamWriter]::new("a.txt", $false, [Text.Encoding]::UTF8)

<小时>

关于需要[System.Text.Encoding]::UTF8时的注意事项:


A note on when [System.Text.Encoding]::UTF8 is needed:

与 Window PowerShell 不同,.NET 默认为 UTF-8(PowerShell [Core] (v6+) 现在也这样做).

Unlike Window PowerShell, .NET defaults to UTF-8 (which PowerShell [Core] (v6+) now does too).

  • 当您读取数据时,通常不需要显式请求UTF-8编码.

  • When you read data, you therefore normally don't need to request UTF-8 encoding explicitly.

当您写入数据时,传递[System.Text.Encoding]::UTF8 会产生一个 UTF-8 文件BOM,而依赖于默认 UTF-8 编码创建的文件没有 BOM(这对于跨平台互操作性更好);要显式请求无 BOM 编码,请使用 [System.Text.Utf8Encoding]::new().

When you write data, passing [System.Text.Encoding]::UTF8 results in a UTF-8 file with a BOM, whereas relying on the default UTF-8 encoding creates a file without a BOM (which is better for cross-platform interoperabiliy); to request a BOM-less encoding explicitly, use [System.Text.Utf8Encoding]::new().

这篇关于如何在 Powershell 中使用编码创建 System.IO.StreamWriter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆