.net - 如何在 Powershell 中使用编码创建 System.IO.StreamWriter?
问题描述
我正在尝试在 PowerShell 中使用 UTF8 编码创建 StreamWriter 实例。
$f = New-Object System.IO.StreamWriter "a.txt", $false, [System.Text.Encoding]::UTF8
这会引发错误:New-Object:找不到“StreamWriter”的重载和参数计数:“3”。
我正在尝试调用此构造函数: https ://msdn.microsoft.com/en-us/library/f5f5x7kt(v=vs.110).aspx
解决方案
不过,我想知道我原来的语法有什么问题。
您的原始语法(基本上正确)使用参数模式,其中参数,松散地说,评估如下:
- 不以 , 或 开头的参数
$
被(
视为@
字符串,即使没有被引用;值得注意的是,[
不在这些特殊字符中。
因此,[System.Text.Encoding]::UTF8
被解释为字符串文字System.Text.Encoding
而不是返回实例的表达式,并且找不到System.IO.StreamWriter
第三个参数为字符串的构造函数。
- 不幸的是,错误消息只提到了参数的数量,而没有指出错误的类型可能是原因;这是一个已知问题 - 请参阅此 GitHub 问题。
正如PetSerAl的评论中提到的,正确的解决方案是封闭[System.Text.Encoding]::UTF8
,(...)
以便在表达式模式下强制其评估,从而产生所需的结果。
请注意,上面还暗示"..."
(双引号)周围a.txt
不是必需的(但没有害处),所以我们得到:
注意:为简洁起见,我System.
在以下示例命令中省略了完整类型中的初始组件;例如,IO.StreamWriter
指System.IO.StreamWriter
. 在大多数情况下,在 PowerShell 中指定System.
部件是可选的。
$f = New-Object IO.StreamWriter a.txt, $false, ([Text.Encoding]::UTF8)
请注意,导致它们作为数组(即单个参数)传递给 的,是,
New-Object
各个构造函数参数之间的,其中它(位置上)绑定到数组类型的-ArgumentList
( -Args
) 参数。
顺便说一句:将单个参数按位置传递给单独的参数更常见,并且需要空格来分隔它们;例如,Select-String foo t.txt
被解析为
Select-String -Pattern foo -Path t.txt
.
您自己的答案(自已删除)使用最好避免并且仅碰巧起作用的伪方法语法:
# AVOID: pseudo method syntax.
$f = New-Object IO.StreamWriter("a.txt", $false, [Text.Encoding]::UTF8)
尽管这看起来像一个方法调用(构造函数调用),但它不是,实际上解析如下:
$f = New-Object IO.StreamWriter -ArgumentList ("a.txt", $false, [Text.Encoding]::UTF8)
也就是说,您已将原始参数数组包含在 中(...)
,这会导致其元素以表达式模式解析,包括[Text.Encoding]::UTF8
,这恰好解决了您的问题。
请注意 - 与参数模式不同 - 在表达式模式中,字符串a.txt
必须包含在"..."
(或'...'
)中。
作为旁白:
Set-StrictMode
-Version 2
或更高版本,除其他外,防止使用伪方法语法,但仅(a) 用于两个或多个参数和 (b) 仅当参数列表 ((...)
) 遵循命令名称(而不是参数,如本New-Object
例中) , 和 (c) 仅当命令名称和开头之间没有空格(
时;例如:
& { Set-Strictmode -version 2; foo('a', 'b') }
请注意,PSv5+确实提供了一种基于方法的方式来构造对象,通过暴露在类型信息对象上的静态new()
方法,在这种情况下,所有参数都以表达式模式解析:
# 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
需要的说明:
与 Window PowerShell 不同,.NET默认为UTF-8(PowerShell [Core] (v6+) 现在也是如此)。
因此,当您读取数据时,通常不需要显式请求 UTF-8 编码。
当您写入数据时,将结果传递到带有BOM
[System.Text.Encoding]::UTF8
的 UTF-8 文件中,而依赖默认的UTF-8 编码会创建一个没有BOM 的文件(这对于跨平台互操作性更好);要明确请求无 BOM 编码,请使用[System.Text.Utf8Encoding]::new()
.
推荐阅读
- javascript - 使用 PHP 将 JS 嵌套数组从 localStorage 保存到 MySQL 表
- java - 无法构建具有从 jndi 查找数据源的 Spring Boot 项目
- wpf - 使用 Gong.DragDrop 像 UserControl 一样拖放到 Non-ItemsControl
- r - MuMIn::dredge()。仅排除包含主效应的模型,仅保留具有交互作用的模型
- c++ - C++程序结束而不是重复for循环
- mongodb - 如何在 Mongodb 中按月份和年份范围进行过滤
- entity-framework - 数据库图工具理解Servicestack/Ormlite
- jmeter - 有没有办法配置 JMeter 来收听 kafka 主题?
- json - Vapor 3 内容到 JSON 到字符串
- java - jsf 方法未找到异常,尽管它在那里,javax.el.MethodNotFoundException