我正在使用VB.NET和Azure .NET程序集将文件上传到Azure blob。由于文件很大,我将其分成块,并使用CloudBlockBlob.PutBlock
上传。我遇到的问题是如果我提供的BlockID
长于一个字符,我会得到一个“指定的blob或块内容无效”。来自PutBLock
的错误。如果blockID只是一个字符,则上传很好。
Dim iBlockSize As Integer = 1024 ' KB
Dim alBlockIDs As New ArrayList
Dim iBlockID As Integer = 10
' Create the blob client.
Dim blobClient As CloudBlobClient = storageAccount.CreateCloudBlobClient()
' Retrieve reference to a previously created container.
Dim container As CloudBlobContainer = blobClient.GetContainerReference("mycontainer")
' Retrieve reference to a blob named "myblob".
Dim blockBlob As CloudBlockBlob = container.GetBlockBlobReference("myblob")
Dim buffer(iBufferSize) As Byte
fs.Read(buffer, 0, buffer.Length)
Using ms As New MemoryStream(buffer)
' convert block id to Base64 Encoded string
Dim b64BlockID As String = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(iBlockID.ToString(Globalization.CultureInfo.InvariantCulture)))
' write the blob block
blockBlob.PutBlock(b64BlockID, ms, Nothing)
alBlockIDs.Add(b64BlockID)
iBlockID += 1
End Using
如果iBlockID = 1
,PutBlock
方法工作正常(我仍然需要解决每个块的blockID长度相同的问题,我稍后会担心)。有什么想法发生了什么?我目前正在使用本地Azure存储模拟器进行测试。
答案 0 :(得分:1)
无法确认,但您的代码中可能存在一些机会,即您需要重叠创建这些缓冲区的内存。请参考以下工作代码以块的形式上传Blob。以下代码使用块大小 10240(10KB),但可以轻松更改
Dim fileName As String = "D:\Untitled.png"
Dim fileSize As Long = New FileInfo(fileName).Length
Dim blockNumber As UInteger = 0
Dim blocksize As UInteger = 10240 '10KB
Dim blockIdList As List(Of String) = New List(Of String)
Using fs As New FileStream(fileName, FileMode.Open, FileAccess.Read)
Do While (fileSize > 0)
Dim bufferSize As UInteger
'Last block of file can be less than 10240 bytes
If (fileSize > blocksize) Then
bufferSize = blocksize
Else
bufferSize = fileSize
End If
Dim buffer(bufferSize) As Byte
Dim br As New BinaryReader(fs)
'move the file system reader to the proper position
fs.Seek(blocksize * blockNumber, SeekOrigin.Begin)
br.Read(buffer, 0, bufferSize)
Using ms As New MemoryStream(buffer, 0, bufferSize)
'convert block id to Base64 Encoded string
Dim b64BlockID As String = Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("BlockId{0}", blockNumber.ToString("0000000"))))
blockBlob.PutBlock(b64BlockID, ms, Nothing)
blockIdList.Add(b64BlockID)
End Using
blockNumber += 1
fileSize -= blocksize
Loop
blockBlob.PutBlockList(blockIdList)
End Using