2011-09-01 57 views
3

我试图使用.net API查找大型数据文件。出于某种原因,我无法使其工作。 这里是我的代码:Seek方法在Powershell脚本中不起作用

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

编辑:仍试图找出这一点。有谁知道我还可以尝试找到有关此问题的信息吗?是否有可能向Microsoft脚本人员发送问题?

此致

吉斯利

回答

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 
} 

感谢您的帮助

吉斯利

5

Seek方法返回流内的新的位置,这是为什么你具有多个打印出来。

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

  1. 确认文件比4K尺寸更大。
  2. 尝试打印出所有行,而不是仅包含单词“错误”的行。这可能会给你一个线索
  3. StreamReader是一个基础流缓冲包装,所以Seek和Position可能不会像你期望的那样工作。考虑http://geekninja.blogspot.com/2007/07/streamreader-annoying-design-decisions.html。尝试加入$reader.DiscardBufferedData()之前寻求。
+0

@RB - 感谢您的答复。无论我使用的是什么,而不是0,如果我放1,输出为1.另外,如果在使用0时查看输出,则最后一个数字应该是读取的字节数。或者至少我认为这是... – Gisli

+0

没错。 Seek正在返回您所寻找的偏移量。因此,如果您寻求1234,它将返回1234.请参阅http://msdn.microsoft.com/en-us/library/system.io.stream.seek.aspx中的“返回值” –

+0

@RB - 好的解释很多。我认为它会让我转到流中的特定位置。那么我该如何在这个位置开始阅读? – Gisli

0

我也有类似的问题。查找位置被打印在控制台上。我只需将返回值分配给某个变量,并解决了问题。

所以不是:

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

我不得不写类似:

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

问候, Thejasvi V

相关问题