我在确切地了解正在发生的事情以及发生的原因时遇到了一些麻烦。我有一个小功能,可以捕获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?
答案 0 :(得分:3)
PetSerAl是正确的(一如既往),但是也许需要更多解释。从函数返回数组时,PowerShell会展开该数组并将单个元素返回给调用方。在那里,它们被收集到常规数组(System.Object[]
)中。
为防止这种情况,您需要在返回数组结果时将其包装在另一个数组中。 PowerShell将仅展开外部数组,并将嵌套数组作为单个元素传递给调用方,从而保留类型。可以认为它是一种“传输编码”。使用一元数组构造运算符(,
)来做到这一点:
return ,$ByteArray