Sharing file access with other applications
Whenever someone looms over the corner of my desk it's for one of three reasons. 1. I broke something, 2. someone needs a script written for them or 3. they are took a stab at a script and need assistance fixing/completing it.
This instance falls in the second category. A process was running and was generating a log file and the person at my desk wanted to be able to read the log file without locking it so that the process could continue writing to it. Using native PowerShell commands, I couldn't think of anything off the top of my head to do what they wanted. Get-Content locks the file temporarily, even if its for a brief millasecond at times, and if the other process want to write to the file then at best the log entry is skipped and at worst the process terminates with an error.
Since PowerShell is built on top of .NET this means that those methods are easily usable inside of PowerShell. After a few moments of Googling around I figured out the solution, and thanks to System.IO.FileStream, this becomes a simple process. The below code shows how I open, read the file, and show it to screen. It's quick, ugly, and dirty but it works. I was not looking to store this data ever, just needed to monitor the file for a little bit until it was satisfied that the process had ended.
[System.IO.FileStream]$fileStream = [System.IO.File]::Open($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
$byteArray = New-Object byte[] $fileStream.Length
$encoding = New-Object System.Text.UTF8Encoding $true
$data = while ($fileStream.Read($byteArray, 0, $byteArray.Length))
{
$encoding.GetString($byteArray)
}
$fileStream.Dispose()
Write-Host $data
By using [System.IO.FileShare]::ReadWrite, this prevents the file from being locked when read so it can still be written to by the other processes accessing the files.
Not something super complex or interesting, but useful non the less.