Возможно, это будет работать для вас.Он пытается прочитать строки файла как можно быстрее, но с отличием от вашего второго подхода (который примерно равен тому, что сделал бы [System.IO.File]::ReadAllLines()
).
Чтобы собрать строки, яиспользовать объект List, который будет работать быстрее, чем добавление в массив с помощью +=
$p = "Seachterm:Search"
$path = "\\remoteserver\c$\temp\tryingtofigurethisout.log"
if (!(Test-Path -Path $path -PathType Leaf)) {
Write-Warning "File '$path' does not exist"
}
else {
try {
$fileStream = [System.IO.FileStream]::new($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)
$streamReader = [System.IO.StreamReader]::new($fileStream)
# or use this syntax:
# $fileMode = [System.IO.FileMode]::Open
# $fileAccess = [System.IO.FileAccess]::Read
# $fileShare = [System.IO.FileShare]::ReadWrite
# $fileStream = New-Object -TypeName System.IO.FileStream $path, $fileMode, $fileAccess, $fileShare
# $streamReader = New-Object -TypeName System.IO.StreamReader -ArgumentList $fileStream
# use a List object of type String or an ArrayList to collect the strings quickly
$lines = New-Object System.Collections.Generic.List[string]
# read the lines as fast as you can and add them to the list
while (!$streamReader.EndOfStream) {
$lines.Add($streamReader.ReadLine())
}
# close and dispose the obects used
$streamReader.Close()
$fileStream.Dispose()
# do the 'Contains($p)' after reading the file to not slow that part down
$lines.ToArray() | Where-Object { $_.Contains($p) } | Select-Object -Last 1
}
catch [System.IO.IOException] {}
}
. В основном, он выполняет то же, что и ваш второй код, но с той разницей, что при использовании только StreamReader
файлаоткрывается с помощью [System.IO.FileShare]::Read
, тогда как этот код открывает файл с [System.IO.FileShare]::ReadWrite
Обратите внимание, что при этом могут возникать исключения, поскольку другое приложение имеет права на запись в файл, следовательно, try{...} catch{...}
Надеюсь, это поможет