寻求方法不在Powershell脚本中工作

时间:2011-09-01 11:10:44

标签: .net powershell file-io seek

我正在尝试使用.net API来搜索大型数据文件。出于某种原因,我无法使其发挥作用。 这是我的代码:

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"
    }
}

}

如果我使用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

如果我尝试使用4096而不是0,它只写出:

4096

我原本以为它会写出与前两个分开的相同的线。

有人能看到问题吗?我有另一个问题让我这样做。有关更多背景信息,请参阅this

编辑:仍然试图解决这个问题。有谁知道我还可以尝试找到有关此问题的信息?是否可以向微软脚本人发送问题?

祝你好运

Gísli

3 个答案:

答案 0 :(得分:5)

Seek方法返回流中的新位置,这就是打印出数字的原因。

至于为什么你没有得到输出:

  1. 确认文件大小超过4K。
  2. 尝试打印出所有行,而不仅仅是打印出“Error”字样的行。这可能会给你一个线索
  3. StreamReader是基本流周围的缓冲包装器,因此Seek和Position可能无法像您期望的那样工作。考虑http://geekninja.blogspot.com/2007/07/streamreader-annoying-design-decisions.html。尝试在之前添加$reader.DiscardBufferedData() 之前的电话。

答案 1 :(得分: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
 }

感谢您的帮助

吉斯利

答案 2 :(得分:0)

我有类似的问题。搜索到的位置被打印在控制台上。我只需要将返回值赋给某个​​变量,这就解决了问题。

所以而不是:

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

我必须写一些类似的东西:

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

此致 Thejasvi V