When I tried to read a file using a pipeline, edit the contents, and save it, I got unexpected behavior.
Is this correct behavior by design ?
# Create a text file for testing
PS> 'A' | Out-File -FilePath C:\test.txt
# Read file , modified, overwrite
PS> Get-Content -Path C:\test.txt -Raw | ForEach-Object {$_ + 'B'} | Out-File -FilePath C:\test.txt
# I expect that the output is 'AB', but it outputs nothing
PS> Get-Content -Path C:\test.txt -Raw
Yeah this is what you can call by design. Because Get-Content passes items along the pipeline one at a time, it's not going to be done reading the file by the time the Out-File cmdlet is called. In fact, the way the cmdlet is designed, the file handle isn't released until the pipeline is completed, so you can't read _and_ write to a file in the same pipeline.
The short solution is to force all the input to be pulled before sending it along the pipe; this can be done pretty simply with some parentheses:
$Path = 'C:\Test.txt'
'A' | Set-Content -Path $Path
(Get-Content -Path $Path -Raw) | ForEach-Object { $_ + 'B' } | Set-Content -Path $Path
Get-Content -Path $Path -Raw
Given the behaviour of -Raw I don't see why it wouldn't be able to release the file handle early in that particular situation, since it's reading the whole file in one go anyway. That would be a possible feature enhancement, I would think. 馃檪
@vexx32 This is a little off topic but this is a great example of why it'd be nice if commands were disposed directly after EndProcessing. You could place an Out-String before Set-Content and the whole thing would just work.
@SeeminglyScience Good point! I guess this will be a bit easier moving forward. I have a couple PRs to put in first, though. 馃槃
Thanks @vexx32
I understood about the behavior. I appreciate your good solution. 馃槃
May I close this issue ?
Of course! 馃槃
@vexx32 Please open new tracking issue if you plan to pull a fix.
@iSazonov a true fix is pretty dicey but some of the changes necessary for #9900 will make this much less tricky to handle, as the file handle should be closed as soon as the command is done with its output.
I'll have to see if that actually is the case or there needs to be changes in Get-Content specifically. I'll open a tracking issue. 馃憤