I have a working script in PowerShell:
$file = Get-Content -Path HKEY_USERS.txt -Raw
foreach($line in [System.IO.File]::ReadLines("EXCLUDE_HKEY_USERS.txt"))
{
$escapedLine = [Regex]::Escape($line)
$pattern = $("(?sm)^$escapedLine.*?(?=^\[HKEY)")
$file -replace $pattern, ' ' | Set-Content HKEY_USERS-filtered.txt
$file = Get-Content -Path HKEY_USERS-filtered.txt -Raw
}
For each line in EXCLUDE_HKEY_USERS.txt it is performing some changes in file HKEY_USERS.txt. So with every loop iteration it is writing to this file and re-reading the same file to pull the changes. However, Get-Content is notorious for memory leaks, so I wanted to refactor it to StreamReader and StreamWriter, but I'm a having a hard time to make it work.
As soon as I do:
$filePath = 'HKEY_USERS-filtered.txt';
$sr = New-Object IO.StreamReader($filePath);
$sw = New-Object IO.StreamWriter($filePath);
I get:
New-Object : Exception calling ".ctor" with "1" argument(s): "The process cannot access the file
'HKEY_USERS-filtered.txt' because it is being used by another process."
So it looks like I cannot use StreamReader and StreamWriter on same file simultaneously. Or can I?
[System.IO.File]::ReadLines( )is the way to go in this case.Get-Contentwithout the-Rawswitch doesn't lead to memory leaks it just adds, honestly uneeded, ETS properties to each line (each object of the file) that's why it's slow.[System.IO.File]::ReadAllText( )andGet-Content -RawNew-Object SomeType(arg1, ...), useNew-Object SomeType [-ArgumentList] arg1, ...- PowerShell cmdlets, scripts and functions are invoked like shell commands, not like methods. That is, no parentheses around the argument list, and whitespace-separated arguments (,constructs an array as a single argument, as needed for-ArgumentList). However, method syntax is required if you use the PSv5+[SomeType]::new()constructor-call method. See this answerReadLinesindeed consumes much less memory thanGet-Content, but it has a problem with regexes.