3

PowerShell では、標準入力をファイルにリダイレクトする通常の方法は、ファイルの内容をパイプすることです。

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

ただし、ファイルが非常に大きい場合、PowerShell は大量のメモリを消費し始めます。small を使用すると、コマンドへの行のフィードの開始-ReadCount速度が向上するように見えGet-Contentますが、メモリ消費量は依然として大きくなります。

メモリ使用量が非常に多いのはなぜですか? 必要がないのに、PowerShell がファイルの内容をメモリに保持しているのでしょうか。それを軽減する方法はありますか?

4

2 に答える 2

4

次の関数は、.NET StreamReaderクラスを使用してファイルを 1 行ずつ読み取り、各行をパイプラインに送信します。これを私のメモリ使用量に送信Out-Nullすると、約 2,000,000 行のログ ファイル (約 186 MB) で実行されている間に、数十 KB しか増加しませんでした。

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
于 2012-10-16T02:43:21.450 に答える
0

考えられる解決策の 1 つが、この記事で提案されています。古いコマンド ラインを使用します。

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

古いスタイルの入力リダイレクトは、同じようにメモリを消費しません。

ただし、これは非常に見苦しく、より複雑なコマンドを作成するために奇妙なことを行う必要があります。私は純粋な PowerShell ソリューションを好みます。

于 2012-10-16T00:29:57.820 に答える