3

.netAPIを使用して大きなデータファイルを検索しようとしています。どういうわけか私はそれを動かすことができません。これが私のコードです:

function check_logs{
  $pos = 8192
  $count = 1
  $path = 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Log\ERRORLOG.2'
  $br = 0
  $reader = [System.IO.File]::OpenText($path)
  $reader.DiscardBufferedData()
  $reader.BaseStream.Seek(0, [System.IO.SeekOrigin]::Begin)
    for(;;){
    $line = $reader.ReadLine()
    if($line -ne $null){$br = $br + [System.Text.Encoding]::UTF8.GetByteCount($line)}
    if($line -eq $null -and $count -eq 0){break}
    if($line -eq $null){$count = 0}
    elseif($line.Contains('  Error:')){
        Write-Host "$line  $br"
    }
}

}

seekメソッドのパラメーターとして0を使用すると、期待どおりに最初からシークしますが、読み取った行を書き込む前にコンソールに0を書き込みます。例:

 0
 2011-08-31 09:26:36.31 Logon       Error: 17187, Severity: 16, State: 1.  4101
 2011-08-31 09:26:36.32 Logon       Error: 17187, Severity: 16, State: 1.  4489
 2011-08-31 09:26:38.25 Logon       Error: 17187, Severity: 16, State: 1.  4929
 2011-08-31 09:26:38.25 Logon       Error: 17187, Severity: 16, State: 1.  5304
 2011-08-31 09:26:43.75 Logon       Error: 17187, Severity: 16, State: 1.  6120

0の代わりに4096を使用してシークしようとすると、次のように書き出されるだけです。

4096

最初の2つを除いて、最初の行と同じ行を書き出すと思いました。

誰かが問題を見ることができますか?私はこれに私を導いた別の質問がありました。さらなる背景については、これを参照してください

編集:まだこれを理解しようとしています。この問題に関する情報を他にどこで見つけられるか知っている人はいますか?Microsoftのスクリプト担当者に質問を送信することはできますか?

よろしくお願いします

ギスリ

4

3 に答える 3

5

Seekメソッドは、ストリーム内の新しい位置を返します。そのため、数値が印刷されます。

出力が得られない理由について:

  1. ファイルのサイズが4Kを超えていることを確認してください。
  2. 「エラー」という単語が含まれている行だけでなく、すべての行を印刷してみてください。それはあなたに手がかりを与えるかもしれません
  3. StreamReaderは、ベースストリームのバッファリングされたラッパーであるため、SeekとPositionが期待どおりに機能しない場合があります。http://geekninja.blogspot.com/2007/07/streamreader-annoying-design-decisions.htmlを検討してください。シークの$reader.DiscardBufferedData() にへの呼び出しを追加してみてください。
于 2011-09-01T12:05:27.193 に答える
0

それで私はついに答えを見つけました。なんらかの理由で私にはわかりませんが、バイナリリーダーを使用する必要があります。以下は私の完全な機能です:

 function check_logs{
 Write-Host "New test `n`n"
 $pos = 19192
 $path = 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Log\ERRORLOG.2'
 $br = 0
 $b = new-object System.IO.BinaryReader([System.IO.File]::Open($path,[System.IO.FileMode]::Open));
 $required = $b.BaseStream.Length - $pos
 $b.BaseStream.Seek($pos, [System.IO.SeekOrigin]::Begin)
 $bytes = $b.ReadBytes($required)
 $log = [System.Text.Encoding]::Unicode.GetString($bytes)
 $split = $log.Split("`n")
 foreach($s in $split)
 {
     if($s.contains("  Error:"))
     {
         Write-Host $s  "`n"
     }
 }
 $b.close
 }

助けてくれてありがとう

ギスリ

于 2011-09-12T11:46:22.633 に答える
0

私も同様の問題を抱えていました。求められた位置がコンソールに印刷されていました。戻り値を変数に割り当てるだけで、問題は解決しました。

したがって、代わりに:

$reader.BaseStream.Seek(0, [System.IO.SeekOrigin]::Begin)

私は次のようなものを書かなければなりませんでした:

$pos = $reader.BaseStream.Seek(0, [System.IO.SeekOrigin]::Begin)

よろしく、Thejasvi V

于 2014-01-30T05:38:51.773 に答える