Клаудблоб.DownloadToStream возвращает значение null

Я пытаюсь загрузить файл из cloudBlob через stream. Я ссылаюсь на эту статью CloudBlob

вот код для загрузки blob

public Stream DownloadBlobAsStream(CloudStorageAccount account, string blobUri)
{
    Stream mem = new MemoryStream();
    CloudBlobClient blobclient = account.CreateCloudBlobClient();
    CloudBlockBlob blob = blobclient.GetBlockBlobReference(blobUri);

    if (blob != null)
        blob.DownloadToStream(mem);

    return mem;
}  

и код для преобразования его в массив байтов

    public static byte[] ReadFully(Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }  

но я всегда получаю значение null. Ниже приводится содержимое файла streamed.

enter image description here

что в этом плохого? Пожалуйста помочь.

редактировать

установка положения в 0 внутри ReadFully метод не допускается, поэтому я помещаю его внутрь DownloadBlobAsStream

Это должно работать так:

public Stream DownloadBlobAsStream(CloudStorageAccount account, string blobUri)
{
    Stream mem = new MemoryStream();
    CloudBlobClient blobclient = account.CreateCloudBlobClient();
    CloudBlockBlob blob = blobclient.GetBlockBlobReference(blobUri);

    if (blob != null)
        blob.DownloadToStream(mem);
    mem.Position = 0;   
    return mem;
} 

3 ответов


ваша проблема в том, что ваш указатель входного потока установлен в конец пара (см. снимок экрана, длину и положение показывают одно и то же значение), поэтому, когда вы читаете его, вы всегда получаете null. Вам нужно будет установить указатель входного потока на 0, используя поток.Позиция = 0 как показано ниже:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16 * 1024];

    input.Position = 0; // Add this line to set the input stream position to 0

    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
} 

Как насчет использования метода OpenRead () для объекта CloudBlob?

public static string ReadFully(string blobUri, string itemUri)
{
    // e.g. itemUri == "foo.txt"
    //   if there is a folder "bar" with foo.txt, provide instead: "bar/foo.txt"
    CloudBlobContainer cloudBlobContainer = new CloudBlobContainer(new Uri(blobUri));
    CloudBlob blobReference = cloudBlobContainer.GetBlobReference(itemUri);

    using (var stream = blobReference.OpenRead())
    {
        using (StreamReader reader = new StreamReader(stream))
        {
            return reader.ReadToEnd();
        }
    }
}

Я попытался реализовать код выше, но, к моему удивлению, функция GetBlockBlobReference не присутствовал в CloudBlobClient а в CloudBlockBlob.

возможно, DLL изменились со временем.

поэтому я представляю вам свою адаптацию:

public class BlobStorageHelper
{
    private readonly CloudBlobClient _blobClient;
    protected readonly CloudStorageAccount StorageAccount;
    public string _containerName { get; set; }

    public BlobStorageHelper()

    {
        _blobClient = base.StorageAccount.CreateCloudBlobClient();
        _containerName = ConfigurationManager.AppSettings["StorageContainerName"];
        StorageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]);
    }

    protected Stream DownloadBlobAsStream(string blobUri)
    {
        CloudStorageAccount account = this.StorageAccount;
        CloudBlockBlob blob = GetBlockBlobReference(account, blobUri);

        Stream mem = new MemoryStream();
        if (blob != null)
        {
            blob.DownloadToStream(mem);                
        }

        return mem;
    }

    private CloudBlockBlob GetBlockBlobReference(CloudStorageAccount account, string blobUri)
    {
        string blobName = blobUri.Substring(blobUri.IndexOf("/" + _containerName + "/")).Replace("/" + _containerName + "/", "");
        CloudBlobClient blobclient = account.CreateCloudBlobClient();
        CloudBlobContainer container = _blobClient.GetContainerReference(_containerName);
        container.CreateIfNotExists();
        CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
        return blob;
    }


    public byte[] DownloadBlobAsByeArray(string blobUri)
    {
        Stream inputStream = DownloadBlobAsStream(blobUri);

        byte[] buffer = new byte[16 * 1024];

        inputStream.Position = 0; // Add this line to set the input stream position to 0

        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }


}