使用StreamWriter()写入与StreamReader()相同的文件

时间:2016-01-18 11:11:23

标签: powershell

我想在多个文件中查找并替换某个字符串。其中一些文件可能比较大,所以我使用StreamReader命名空间中的System.IO类。

我遇到的问题是我不想将新值写入新文件(这是我目前所拥有的)。我想只是"更新"当前的文件。

$currentValue = "B";
$newValue = "A";

# Loop through all of the directories and update with new details. 
foreach ($file in $Directories) {
    $streamReader = New-Object System.IO.StreamReader -Arg "$file"
    $streamWriter = [System.IO.StreamWriter] "$file"
    # Switching $streamWriter to the below works.
    # $streamWriter = [System.IO.StreamWriter] "C:\Temp\newFile.txt"

    while($line = $streamReader.ReadLine()){
        # Write-Output "Current line value is $line";
        $s = $line -replace "$currentValue", "$newValue"
        # Write-Output "The new line value is $s"
        $streamWriter.WriteLine($s);
    }

    # Close the streams ready for the next loop.
    $streamReader.close();
    $streamWriter.close();
}

Write-Output "The task has complete."

有谁知道我怎么做才能做到这一点?

2 个答案:

答案 0 :(得分:5)

您无法同时从同一个文件读取/写入。不是使用StreamReaderStreamWriter,也不是使用任何其他常用方法。如果您需要修改现有文件而不能(或者不想)将其整个内容读入内存,则必须将修改后的内容写入临时文件,然后将原始内容替换为两个文件关闭后的临时文件。

示例:

$filename = (Get-Item $file).Name

$streamReader = New-Object IO.StreamReader -Arg $file
$streamWriter = [System.IO.StreamWriter] "$file.tmp"

...

$streamReader.Close(); $streamReader.Dispose()
$streamWriter.Close(); $streamWriter.Dispose()

Remove-Item $file -Force
Rename-Item "$file.tmp" -NewName $filename

答案 1 :(得分:-1)

if ( $my_infile.Length -gt 0 ) {
  [string] $full_name_infile = $my_dir + "\" + $my_infile
  $f1 = Get-Content($full_name_infile) -ErrorAction Stop
  if ( $f1.count -gt 0 ) { 
       [string] $fout1_dir = $my_dir 
       [string] $fout1_name = $fout1_dir + "\"  + $my_infile + ".temp"
       $fmode = [System.IO.FileMode]::Append
       $faccess = [System.IO.FileAccess]::Write
       $fshare = [System.IO.FileShare]::None
       $fencode = [System.Text.ASCIIEncoding]::ASCII
       $stream1 = New-Object System.IO.FileStream $fout1_name, $fmode, $faccess, $fshare
       $fout1 = new-object System.IO.StreamWriter $stream1, $fencode
  }

  for ( $x=0; $x -lt $f1.count; $x++ ) {
    $line = $f1.Get( $x )
    if ( $line.length -eq 0 ) {
       $nop=1
    } else {
         if (  $line.Substring( $line.Length-1 , 1 ) -eq "," ) { $line = $line + " "; }
         $fout1.WriteLine( $line );
    }

  }
  $fout1.Close()
  $fout1.Dispose()
  move-item  $fout1_name $full_name_infile -force 
}