Set-Content偶尔失败,"Stream不可读"

dan*_*hel 8 powershell

我有一些PowerShell脚本在构建之前准备文件.其中一个操作是替换文件中的某些文本.我使用以下简单函数来实现此目的:

function ReplaceInFile {
    Param(
        [string]$file,
        [string]$searchFor,
        [string]$replaceWith
    )

    Write-Host "- Replacing '$searchFor' with '$replaceWith' in $file"

    (Get-Content $file) |
    Foreach-Object { $_ -replace "$searchFor", "$replaceWith" } |
    Set-Content $file
}
Run Code Online (Sandbox Code Playgroud)

此函数偶尔会因错误而失败:

Set-Content : Stream was not readable.
At D:\Workspace\powershell\ReplaceInFile.ps1:27 char:5
+     Set-Content $file
+     ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (D:\Workspace\p...AssemblyInfo.cs:String) [Set-Content], ArgumentException
    + FullyQualifiedErrorId : GetContentWriterArgumentError,Microsoft.PowerShell.Commands.SetContentCommand
Run Code Online (Sandbox Code Playgroud)

发生这种情况时,结果是一个空文件和一个不愉快的构建.任何想法为什么会这样?我应该做些什么呢?

Mar*_*ndl 8

对不起,我不知道为什么会这样,但你可以Replace-TextInFile 尝试一下我的功能.如果我没记错的话,我Get-contet也会遇到类似的问题:

function Replace-TextInFile
{
    Param(
        [string]$FilePath,
        [string]$Pattern,
        [string]$Replacement
    )

    [System.IO.File]::WriteAllText(
        $FilePath,
        ([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement)
    )
}
Run Code Online (Sandbox Code Playgroud)

  • 完美,我有同样的问题,这种方法似乎工作得更好.我将[System.Text.Encoding] :: UTF8添加到读取和写入. (2认同)

Cha*_*had 8

我遇到了这个问题,结果是我试图更改的文件是在 Visual Studio 中打开的解决方案的一部分。在运行之前关闭 Visual Studio 解决了问题!


llo*_*oyd 5

正如joelsand所提到的,Martin Brandl的答案可以稍作改进。

function Replace-TextInFile
{
    Param(
        [string]$FilePath,
        [string]$Pattern,
        [string]$Replacement, 
        [System.Text.Encoding] $Encoding
    )

    if($Encoding) {
        [System.IO.File]::WriteAllText(
            $FilePath,
            ([System.IO.File]::ReadAllText($FilePath, $Encoding) -replace $Pattern, $Replacement),
            $Encoding
        )
    } else { 
        [System.IO.File]::WriteAllText(
            $FilePath,
            ([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement)
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

例子:

$encoding = [System.Text.Encoding]::UTF8
Replace-TextInFile -FilePath $fullPath -Pattern $pattern -Replacement $replacement -Encoding $encoding
Run Code Online (Sandbox Code Playgroud)