Seek 方法在 Powershell 脚本中不起作用

发布于 2024-12-02 08:28:13 字数 1509 浏览 2 评论 0原文

我正在尝试使用 .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 作为 seek 方法的参数,它会按预期从头开始查找,但它还会在写入读取的行之前将 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

除了前两行之外,我本以为它会写出与第一行相同的行。

有人能看到问题吗?我还有另一个问题让我想到了这一点。有关更多背景信息,请参阅

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

最好的问候

吉斯利

I´m trying to use the .net API to seek in a large data file. For some reason I am unable to make it work.
Here is my code:

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

}

If I use 0 as a parameter for the seek method it seeks from the beginning as expected but it also writes 0 out to the console before it writes the lines read. Example:

 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

If I try to seek using 4096 instead of 0 it only writes out:

4096

I would have thought it would write out the same lines as the first one did apart from the first two.

Can someone see the problem? I had another question that got me to this. For further background see this

EDIT: Still trying to figure this out. Does anyone know where else I could try to find information regarding this problem? Is it possible to send questions to the Microsoft scripting guy?

Best regards

Gísli

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一世旳自豪 2024-12-09 08:28:13

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

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

  1. 确认文件大小大于 4K。
  2. 尝试打印所有行,而不仅仅是其中包含“错误”一词的行。这可能会给您一个线索
  3. StreamReader 是基本流的缓冲包装器,因此 Seek 和 Position 可能不会像您期望的那样工作。考虑http://geekninja.blogspot.com/2007/07/streamreader-annoying-design -decisions.html。尝试在搜索之前添加对$reader.DiscardBufferedData()的调用。

The Seek method returns the new position within the stream, which is why you are having a number printed out.

As to why you are not getting an output:

  1. Confirm the file is greater than 4K in size.
  2. Try printing out all lines, rather than just lines with the word "Error" in them. That might give you a clue
  3. StreamReader is a buffered wrapper around the base stream, so Seek and Position may not work quite like you expect. Consider http://geekninja.blogspot.com/2007/07/streamreader-annoying-design-decisions.html. Try adding in a call to $reader.DiscardBufferedData() before the seek.
喜爱纠缠 2024-12-09 08:28:13

所以我终于找到了答案。由于某种我不知道的原因,我必须使用二进制阅读器。
以下是我的完整功能:

 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
 }

帮助

感谢Gísli 的

So I finally found the answer. For some reason unknown to me I have to use a binary reader.
Here below is my complete function:

 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
 }

Thanks for the help

Gísli

卷耳 2024-12-09 08:28:13

我有类似的问题。控制台上打印出寻找的位置。我只需要将返回值分配给某个变量,就解决了问题。

因此,

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

我必须写一些类似的内容,而不是:

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

问候,
塞贾斯维五世

I had a similar problem. The seeked-off position was getting printed on the console. I just had to assign the return value to some variable, and that solved the problem.

So instead of:

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

I had to write something like:

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

Regards,
Thejasvi V

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文