在Powershell中将标准输入重定向到大文件 - 内存消耗

时间:2012-10-16 00:29:58

标签: powershell memory-leaks stdin large-files

在PowerShell中,将标准输入重定向到文件的常规方法是管道文件的内容:

Get-Content input-file.txt | Write-Host

但是,如果文件非常大,PowerShell会开始消耗大量内存。使用较小的-ReadCount似乎可以加快Get-Content开始向命令中输入行的速度,但内存消耗仍然很大。

为什么内存使用率如此之高? PowerShell是否保留了内存中的文件内容,即使它不需要?有没有办法减轻这种影响?

2 个答案:

答案 0 :(得分:4)

以下函数将使用.NET StreamReader类逐行读取文件,并沿管道发送每一行。将此内容发送到Out-Null我的内存使用量只增加了几十KB,而它在近2,000,000行日志文件(~186 MB)上执行:

function Get-ContentByLine {
  param (
    [Parameter(Mandatory=$true,ValueFromPipeline=$true)][PsObject]$InputObject
  )

  begin {
    $line = $null
    $fs = [System.IO.File]::OpenRead($InputObject)
    $reader = New-Object System.IO.StreamReader($fs)
  }

  process {
    $line = $reader.ReadLine()
    while ($line -ne $null) {
        $line
        $line = $reader.ReadLine()
    }
  }

  end {
    $reader.Dispose();
    $fs.Dispose();
  }
}

您可以这样调用它:

PS C:\> Get-ContentByLine "C:\really.big.log" | Out-Null

答案 1 :(得分:0)

this article建议了一种可能的解决方案。使用旧命令行:

cmd.exe /C "ECHO < input-file.txt"

旧式输入重定向不会以相同方式消耗内存。

但是,这非常难看,让你做一些奇怪的事情来构建更复杂的命令。我更喜欢纯粹的PowerShell解决方案。