Different Azure blob streams when using .Net client vs. REST interface

Posted by knightpfhor on Stack Overflow See other posts from Stack Overflow or by knightpfhor
Published on 2010-04-08T03:45:04Z Indexed on 2010/04/08 3:53 UTC
Read the original article Hit count: 717

Filed under:
|

I have encountered an unusual difference in the way that the .Net client for Azure and the direct REST API bring back streams of binary data. If I use the CloundBlob.DownloadToStream() vs. getting the response stream from the HTTP response, I get streams with the same length, but different content. Specifically the REST response seems to 0 out a series of bytes.

I've discovered this issue because I'm trying to use the byte range feature for blobs which is currently not supported in the .Net client (if I'm wrong on this point and someone can point at where I can do this it might make the rest of this question irrelevant).

If I upload a binary representation of the first 2k unicode characters with this code:

Public Sub WriteFoo()
    Dim Blob As CloudBlob
    Dim Stream1 As MemoryStream
    Dim Container As CloudBlobContainer
    Dim Builder As StringBuilder
    Dim NextCharacter As String
    Dim Formatter As BinaryFormatter

    Container = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudBlobClient.GetContainerReference("testcontainer")

    Container.CreateIfNotExist()

    Blob = Container.GetBlobReference("Foo")

    Stream1 = New MemoryStream()

    Builder = New Text.StringBuilder()

    For Index As Integer = 1 To 2000
        Select Case Index
            Case Is <= 9
                NextCharacter = ChrW(9)

            Case Is <= 31
                NextCharacter = Environment.NewLine

            Case 127
                NextCharacter = Environment.NewLine

            Case Else
                NextCharacter = ChrW(Index)

        End Select

        Builder.Append(NextCharacter)
    Next

    Formatter = New BinaryFormatter()

    Formatter.Serialize(Stream1, Builder.ToString())

    Stream1.Position = 0

    Blob.UploadFromStream(Stream1)
End Sub

Then try to access it with the following code:

Public Sub ReadFoo()
        Dim Blob As CloudBlob
        Dim Request As System.Net.HttpWebRequest
        Dim Response As System.Net.WebResponse
        Dim ResponseSize As Integer
        Dim ResponseBuffer As Byte()
        Dim ResponseStream As Stream
        Dim Stream1 As MemoryStream
        Dim Stream2 As MemoryStream
        Dim Container As CloudBlobContainer
        Dim Byte1 As Integer
        Dim Byte2 As Integer

        Container = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudBlobClient.GetContainerReference("testcontainer")

        Container.CreateIfNotExist()

        Blob = Container.GetBlobReference("Foo")

        Stream1 = New MemoryStream()
        Stream2 = New MemoryStream()

        Blob.DownloadToStream(Stream1)

        Request = DirectCast(System.Net.WebRequest.Create(Blob.Uri), System.Net.HttpWebRequest)

        Request.Headers.Add("x-ms-version", "2009-09-19")
        Request.Headers.Add("x-ms-range", String.Format("bytes={0}-{1}", 0, Integer.MaxValue))
        Blob.Container.ServiceClient.Credentials.SignRequest(Request)

        Response = Request.GetResponse()

        ResponseStream = Response.GetResponseStream()

        ResponseSize = CInt(Response.ContentLength)

        ReDim ResponseBuffer(ResponseSize - 1)

        ResponseStream.Read(ResponseBuffer, 0, ResponseSize)

        Stream2.Write(ResponseBuffer, 0, ResponseSize)

        Stream1.Position = 0
        Stream2.Position = 0

        If Stream1.Length <> Stream2.Length Then
            System.Diagnostics.Debug.WriteLine(String.Format("Streams a different length. 1: {0}. 2: {1}", Stream1.Length, Stream2.Length))
        Else
            While Stream1.Position < Stream1.Length
                Byte1 = Stream1.ReadByte()
                Byte2 = Stream2.ReadByte()

                If Byte1 <> Byte2 Then
                    System.Diagnostics.Debug.WriteLine(String.Format("Streams differ at position {0}, 1: {1}. 2: {2}", Stream1.Position - 1, Byte1, Byte2))
                End If
            End While
        End If
    End Sub

Past all certain point all of the data in Stream2 (the data I've retrieved from the REST api) ends up being 0. To make matters even more confusing, when I reverse the order that I put the characters in the string e.g. For Index As Integer = 2000 To 1 rather than For Index As Integer = 1To 2000 it all works OK.

Any help is much appreciated. My computer is sick of me swearing at it.

© Stack Overflow or respective owner

Related posts about Azure

Related posts about azure-storage-blobs