.net方法使用的文件,但Powershell cmdlet不使用

时间:2018-07-31 16:43:45

标签: .net powershell powershell-v2.0

要在Powershell中打开和读取文件,请使用以下两种方法之一:

Get-Content $path

[System.IO.File]::OpenRead($path)

读取另一个进程正在使用的日志文件时,Get-Content似乎没有任何问题。然后,与.NET方法相比,PowerShell cmdlet仍然很慢并且使用更多的内存。但是,当我尝试使用.NET方法时,出现以下错误:

  

“该进程无法访问文件'XYZ',因为该文件正由   另一个过程。”

Q1:为什么Powershell cmdlet可以使用.net方法访问文件?

Q2:如何使用.net方法读取文件?由于获取内容对于大约80 MB的日志文件来说太慢了。我通常只读最后一行:

$line = ""
$lineBreak = Get-Date -UFormat "%d.%m.%Y "
$bufferSize = 30
$buffer = New-Object Byte[] $bufferSize
$fs = [System.IO.File]::OpenRead($logCopy)
while (([regex]::Matches($line, $lineBreak)).Count -lt $n) {
    $fs.Seek(-($line.Length + $bufferSize), [System.IO.SeekOrigin]::End) | Out-Null
    $fs.Read($buffer, 0, $bufferSize) | Out-Null
    $line = [System.Text.Encoding]::UTF8.GetString($buffer) + $line
}
$fs.Close()

    ($line -split $lineBreak) | Select -Last $n
}

question

任何帮助,我们将不胜感激!

PS!我正在使用Powershell 2.0,无法终止正在使用该文件的进程。另外,我没有对该文件的写入权限,只能读取。

2 个答案:

答案 0 :(得分:3)

PetSerAl像往常一样提供了简短的注释,该注释提供了有效的解决方案并暗含一种解释:

为防止发生<div id="myDiv"> <form> <input type="text"> <select> <option>1</option> </select> <textarea>Text...</textarea> <div> <input type="text"/> </div> <div> <span> <select id="nestedSelect"> <option value="2">2</option> </select> </span> </div> </form> </div> <script> var divElem = document.getElementById("myDiv"); var inputElements = divElem.querySelectorAll("input, select, textarea"); for(let i = 0; i < inputElements.length; i++){ console.log(inputElements[i]); } </script>错误,您必须以共享模式FileShare.ReadWrite打开文件,以便不要将要写入的其他进程写入文件” t拒绝访问。

"The process cannot access the file 'XYZ' because it is being used by another process."(总是)在后台进行操作,这说明了为什么在使用 it 时问题不会浮出水面。

相反,[System.IO.File]::OpenRead()默认为共享模式Get-Content,这意味着其他进程可以读取,但不能写入同一文件。

因此,请改用[System.IO.File]::Open(),它允许您明确指定共享模式:

FileShare.Read

请注意,我从上面的类型名称中省略了$fs = [IO.File]::Open($path, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::ReadWrite) # ... $fs.Close() 组件;此组件在PowerShell中始终是可选的。

答案 1 :(得分:1)

如果可以使用更高版本的PowerShell(至少v3.0),那么Get-Content -Tail是一个不错的选择。我们广泛使用它,性能对于我们的场景来说是好的。

Official docs

  

从文件或其他项目的末尾获取指定的行数。
  Windows PowerShell 3.0中引入了此参数。
  您可以使用“ Tail”参数名称或其别名“ Last”。