返回大字节数组时,PowerShell消耗GB的RAM?

时间:2018-09-17 05:13:54

标签: powershell

我在确切地了解正在发生的事情以及发生的原因时遇到了一些麻烦。我有一个小功能,可以捕获133MB大PNG图像文件的所有字节,将其存储在字节数组中,然后将其返回。可能是某些我不了解的行为,或者是PowerShell中的错误?

$TestFile = 'C:\test.png'

function GetByteArray($InputFile) {
    $ByteArray = [IO.File]::ReadAllBytes($InputFile)

    Write-Host ( 'Type: ' + $ByteArray.GetType() )
    Write-Host ( 'Size: ' + $ByteArray.Length )

    return $ByteArray
}
$NewArray = GetByteArray -InputFile $TestFile

Write-Host ( 'Type: ' + $NewArray.GetType() )
Write-Host ( 'Size: ' + $NewArray.Length )

pause

我期望该函数返回大小约为133MB的[Byte[]],但不会。相反,PowerShell会消耗大约5GB的RAM,在下面打印出错误消息,然后返回[System.Object[]]

Type: byte[]
Size: 140151164
Array dimensions exceeded supported range.
At F:\test.ps1:10 char:10
+   return $ByteArray
+          ~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], OutOfMemoryException
    + FullyQualifiedErrorId : System.OutOfMemoryException

Type: System.Object[]
Size: 134217728
Press Enter to continue...:

我不明白什么?为什么将字节数组转换为对象?为什么要吃掉我几乎所有的RAM?

1 个答案:

答案 0 :(得分:3)

PetSerAl是正确的(一如既往),但是也许需要更多解释。从函数返回数组时,PowerShell会展开该数组并将单个元素返回给调用方。在那里,它们被收集到常规数组(System.Object[])中。

为防止这种情况,您需要在返回数组结果时将其包装在另一个数组中。 PowerShell将仅展开外部数组,并将嵌套数组作为单个元素传递给调用方,从而保留类型。可以认为它是一种“传输编码”。使用一元数组构造运算符(,)来做到这一点:

return ,$ByteArray