我一直在使用PowerShell v3(CTP2)及其新的Invoke-RestMethod做一些工作,如下所示:
调用RestMethod-Uri$dest-method PUT-Credential$cred-InFile$file
然而,我想用它来推送非常的大型二进制对象,因此我希望能够从大型二进制文件中推送范围的字节。
例如,如果我有一个20Gb VHD,我想把它分成几个块,比如说,每个5Gb(不需要先拆分和保存单独的块),然后把它们放到BLOB存储中,比如S3、Rackspace、Azure等。我还假设块大小大于可用内存。
我读过GetContent在大型二进制文件上不能很有效地工作,但这似乎不是一个模糊的要求。有人有任何可以用于此的方法吗,特别是与PowerShell的新Invoke-RestMethod结合使用吗?
我相信您要查找的Invoke-RestMethod参数是
-TransferEncoding Chunked
但是不存在对块或缓冲区大小的控制。如果我错了,有人可以纠正我,但我认为块大小是4KB。每个区块都被加载到内存中,然后被发送,这样你的内存就不会被你发送的文件填满。
要检索文件的部分(块),您可以创建一个System.IO.BinaryReader
,它有一个方便的anddy Read( [Byte[]] buffer, [int] offset, [int] length)
方法。这里有一个简单的功能:
function Read-Bytes {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true, Position = 0)]
[string] $Path
, [Parameter(Mandatory = $true, Position = 1)]
[int] $Offset
, [Parameter(Mandatory = $true, Position = 2)]
[int] $Size
)
if (!(Test-Path -Path $Path)) {
throw ('Could not locate file: {0}' -f $Path);
}
# Initialize a byte array to hold the buffer
$Buffer = [Byte[]]@(0)*$Size;
# Get a reference to the file
$FileStream = (Get-Item -Path $Path).OpenRead();
if ($Offset -lt $FileStream.Length) {
$FileStream.Position = $Offset;
Write-Debug -Message ('Set FileStream position to {0}' -f $Offset);
}
else {
throw ('Failed to set $FileStream offset to {0}' -f $Offset);
}
$ReadResult = $FileStream.Read($Buffer, 0, $Size);
$FileStream.Close();
# Write buffer to PowerShell pipeline
Write-Output -InputObject $Buffer;
}
Read-Bytes -Path C:WindowsSystem32KBDIT142.DLL -Size 10 -Offset 90;