3

I'm having a bit of trouble understanding exactly what is going and why it is happening. I have a small function grabbing all the bytes of a large 133MB PNG image file, storing it in a byte array, and returning it. There is either some behavior I don't understand, or perhaps a bug in 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

I am expecting the function to return a [Byte[]] about 133MB in size, but it does not. Instead PowerShell consumes about 5GB RAM, prints out the error message below, and returns a [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...:

What am I not understanding? Why is the byte array being converted to an object? Why is eating almost all my RAM?

1
  • 1
    You are not returning byte array, but individual bytes. Commented Sep 17, 2018 at 8:32

1 Answer 1

4

PetSerAl is correct (as always), but perhaps a little more explanation is in order. When returning an array from a function PowerShell unrolls that array and returns the individual elements to the caller. There they are gathered into a regular array (System.Object[]).

To prevent this you need to wrap the array result in another array when returning it. PowerShell will only unroll the outer array and pass the nested array to the caller as a single element, thus preserving the type. Think of it as applying a kind of "transport encoding". Use the unary array construction operator (,) to do that:

return ,$ByteArray
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much, this indeed correctly returns the byte array!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.