【发布时间】:2016-01-26 01:07:46
【问题描述】:
我正在编写一个 powershell Cmdlet 来接受对 gzip 压缩文件的文件引用列表并解压缩它们并将它们的文本行放在管道上。我有一些功能,但它使用了大量的内存。有趣的是,完成后,如果我在 powershell 提示符下运行 [System.GC]::Collect() ,它将释放内存。我尝试在循环内运行它,但它影响了性能。有人可以指出我做错了什么。我认为使用管道的好处之一是节省内存。即使我将单个文件引用传递给它,它也会使用比文件大小更多的内存。
这是我的代码。
<#
.SYNOPSIS
Accepts GZip files piped in and outputs decrompessed text to the pipe.
.DESCRIPTION
You can use this function to pipe a list of serveral gzipped files. They will then be decompress and concatenated
and the text will be written to the output where it can be piped to another function.
.PARAMETER PipedFile
A list of gzipped file references.
.EXAMPLE
Get-ChildItem "*.gz" | Decompress-Gzip
#>
Function Decompress-GZip {
Param(
[Parameter(ValueFromPipeline=$true)]
[System.IO.FileInfo]$PipedFile
)
Process {
If ( $PipedFile.Exists -eq $False) {
Write-Host "File $PipedFile does not exist. Skipping."
return
}
$BUFFER_SIZE = 65536
$infile = $PipedFile.FullName
$inputfile = New-Object System.IO.FileStream $inFile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)
$gzipStream = New-Object System.IO.Compression.GzipStream $inputfile, ([IO.Compression.CompressionMode]::Decompress)
try {
$buffer = New-Object byte[]($BUFFER_SIZE)
While (($read = $gzipstream.Read($buffer, 0, $BUFFER_SIZE)) -gt 0) {
$str = [System.Text.Encoding]::ASCII.GetString($buffer,0,$read)
$temp = $str -split "`r`n"
if ($temp.Length -gt 0) {
if ($lastLine) {
$temp[0] = $lastLine + $temp[0]
}
if ($temp.Length -gt 1) {
Write-Output $temp[0..($temp.Length-2)]
}
$lastLine = $temp[($temp.Length-1)]
}
}
} finally {
$gzipStream.Close()
$inputfile.Close()
}
}
}
【问题讨论】:
-
看起来与stackoverflow.com/questions/34968966/… 类似,但由于您的“GC 收集”有效,所以不太一样。如果您正在处理数十个或数百个文件,也许每三个/十个左右的文件只运行一次“GC 收集”可以提高性能并降低内存使用量。
标签: powershell gzip gzipstream