Reputation: 1396
I want to find and replace a certain string in a number of files. Some of these files can be relatively large so I am using the StreamReader
class from the System.IO
namespace.
The issue I have is that I don't want to have to write the new values to a new file (which is what I have currently). I want to just "update" the current files.
$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."
Does anyone know how I could go about doing the above?
Upvotes: 2
Views: 15638
Reputation: 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
}
Upvotes: -1
Reputation: 200503
You can't read and write from/to the same file simultaneously. Not with StreamReader
and StreamWriter
, nor with any other usual method. If you need to modify an existing file and can't (or don't want to) read its entire content into memory you must write the modified content to a temporary file and then replace the original with the temp file after both files were closed.
Example:
$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
Upvotes: 7