Невозможно прочитать открытый файл с помощью двоичного читателя - PullRequest
1 голос
/ 03 января 2012

У меня есть эта функция для чтения журнала ошибок SQL Server, но проблема в том, что я не могу прочитать журнал ошибок, который сервер использует в то время. Я был в Google, и кажется, что флаг Fileshare не работает для powershell. Есть ли какой-нибудь способ установить флаг Fileshare, когда я пытаюсь открыть файл?

    function check_logs{
        param($logs)
        $pos
        foreach($log in $logpos){
            if($log.host -eq $logs.host){
                $currentLog = $log
                break
            }
        }
        if($currentLog -eq $null){
            $currentLog = @{}
            $logpos.Add($currentLog)
            $currentLog.host = $logs.host
            $currentLog.event = $logs.type
            $currentLog.lastpos = 0
        }
        $path = $logs.file
        if($currentLog.lastpos -ne $null){$pos = $currentLog.lastpos}
        else{$pos = 0}
        if($logs.enc -eq $null){$br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open))}
        else{
            $encoding = $logs.enc.toUpper().Replace('-','')
            if($encoding -eq 'UTF16'){$encoding = 'Unicode'}
            $br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open), [System.Text.Encoding]::$encoding)
        }
        $required = $br.BaseStream.Length - $pos
        if($required -lt 0){
            $pos = 0
            $required = $br.BaseStream.Length
        }
        if($required -eq 0){$br.close(); return $null}
        $br.BaseStream.Seek($pos, [System.IO.SeekOrigin]::Begin)|Out-Null
        $bytes = $br.ReadBytes($required)
        $result = [System.Text.Encoding]::Unicode.GetString($bytes)
        $split = $result.Split("`n")
        foreach($s in $split)
         {
            if($s.contains("  Error:"))
            {
                $errorLine = [regex]::Split($s, "\s\s+")
                $err = [regex]::Split($errorLine[1], "\s+")
                if(log_filter $currentLog.event $err[1..$err.length]){$Script:events = $events+ [string]$s + "`n" }         
            }
        }
        $currentLog.lastpos = $br.BaseStream.Position 
        $br.close()
     }

Для ясности ошибка появляется, когда я пытаюсь открыть файл. Сообщение об ошибке:

 Exception calling "Open" with "2" argument(s): "The process cannot access the file
 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Log\ERRORLOG' 
  because it is being used by another process."

Гисли

1 Ответ

0 голосов
/ 03 января 2012

Так что я нашел ответ, и это было довольно просто.

Конструктор двоичного читателя принимает в качестве входных данных поток. Я не определял поток отдельно, и поэтому не заметил, что вы установили флаг FileShare в конструкторе потока.

Мне нужно было изменить это:

{$br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open))}

К этому:

{$br = New-Object System.IO.BinaryReader([System.IO.File]::Open($path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite))}

И тогда это сработало как заклинание.

Гисли

...