【问题标题】:file IO, is this a bug in Powershell?文件 IO,这是 Powershell 中的错误吗?
【发布时间】:2013-01-12 14:04:01
【问题描述】:

我在 Powershell 中有以下代码

$filePath = "C:\my\programming\Powershell\output.test.txt"

try
{
    $wStream = new-object IO.FileStream $filePath, [System.IO.FileMode]::Append, [IO.FileAccess]::Write, [IO.FileShare]::Read

    $sWriter = New-Object  System.IO.StreamWriter $wStream

    $sWriter.writeLine("test")
 }

我不断收到错误:

无法转换参数“1”,其值为:“[IO.FileMode]::Append”,用于 “FileStream”键入“System.IO.FileMode”:“无法转换值 “[IO.FileMode]::Append”键入“System.IO.FileMode”由于无效 枚举值。指定以下枚举值之一 然后再试一次。可能的枚举值为“CreateNew, Create, 打开、OpenOrCreate、截断、追加”。”

我尝试了 C# 中的等价物,

    FileStream fStream = null;
    StreamWriter stWriter = null;

    try
    {
        fStream = new FileStream(@"C:\my\programming\Powershell\output.txt", FileMode.Append, FileAccess.Write, FileShare.Read);
        stWriter = new StreamWriter(fStream);
        stWriter.WriteLine("hahha");
    }

效果很好!

我的 powershell 脚本有什么问题?顺便说一句,我在 powershell 上运行

Major  Minor  Build  Revision
-----  -----  -----  --------
3      2      0      2237

【问题讨论】:

标签: powershell filestream


【解决方案1】:

另一种方法是只使用值的名称,然后让 PowerShell 将其转换为目标类型:

New-Object IO.FileStream $filePath ,'Append','Write','Read'

【讨论】:

  • 是的,我也会采用这种方法。
  • 我不敢相信 powershell 不能处理构造函数中的枚举。他们现在是 5.1 版,这仍然不起作用!
【解决方案2】:

当使用New-Object cmdlet 并且目标类型构造函数接受参数时,您应该使用-ArgumentList 参数(New-Object)或将参数包装在括号中 - 我更喜欢用括号包装我的构造函数:

# setup some convenience variables to keep each line shorter
$path = [System.IO.Path]::Combine($Env:TEMP,"Temp.txt")
$mode = [System.IO.FileMode]::Append
$access = [System.IO.FileAccess]::Write
$sharing = [IO.FileShare]::Read

# create the FileStream and StreamWriter objects
$fs = New-Object IO.FileStream($path, $mode, $access, $sharing)
$sw = New-Object System.IO.StreamWriter($fs)

# write something and remember to call to Dispose to clean up the resources
$sw.WriteLine("Hello, PowerShell!")
$sw.Dispose()
$fs.Dispose()

New-Object cmdlet 在线帮助:http://go.microsoft.com/fwlink/?LinkID=113355

【讨论】:

  • 你同样可以省略括号,因为它只需要一个对象数组,可选地以-ArgumentList开头。你的括号只是让它成为一个单独的表达式;对吗?
  • PowerShell 中数组周围的括号实际上是一个无操作,除了充当标记分隔符。我避免使用这种语法new-object <typename>(arg,arg,...),因为它误导您相信这只是一个 C# 构造函数,而实际上并非如此。使用new-object <typename> arg,arg,... 实际上更少打字。很抱歉我很迂腐,但我已经回答了太多关于为什么 MyPowerShellFunctionThatTakesThreeParameters(1,2,3) 不起作用的问题。 :-)
  • powershell 决策者开始让我感到不安。有一天你不应该使用括号。第二天你就是。我看到你现在也在使用逗号作为构造函数。他们使这变得比需要的更困难。
【解决方案3】:

另一种方法是将枚举括在括号中:

$wStream = new-object IO.FileStream $filePath, ([System.IO.FileMode]::Append), `
    ([IO.FileAccess]::Write), ([IO.FileShare]::Read)

【讨论】:

  • 如果你在构造 FileStream 时使用括号,你的方法会起作用: $wStream = new-object IO.FileStream $filePath([System.IO.FileMode]::Append, [IO.FileAccess]: :Write, [IO.FileShare]::Read)
【解决方案4】:

如果您的目标是写入日志文件或文本文件,那么您可以尝试 PowerShell 中支持的 cmdlet 来实现这一目标吗?

Get-Help Out-File -Detailed

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2011-09-28
    相关资源
    最近更新 更多