CloudBlob.OpenRead () не читает все данные - PullRequest
2 голосов
/ 02 августа 2011

В клиентской библиотеке хранилища Windows Azure метод CloudBlob.OpenRead () считывает только 4 МБ данных.Как я могу прочитать полный поток, используя метод OpenRead.

CloudBlob blob = container.GetBlobReference(filename);
Stream stream = blob.OpenRead();

Я должен использовать метод OpenRead.Невозможно использовать DownloadToFile или DownloadToStream.

РЕДАКТИРОВАТЬ: Код потребителя, который находится за пределами моей области вызовов

stream.CopyTo(readIntoStream);

CopyTo является методом расширения.

public static int CopyTo(this Stream source, Stream destination)
        {
            byte[] buffer = new byte[BUFFER_SIZE];
            int bytesRead;
            int bytesCopied = 0;

            do
            {
                bytesRead = source.Read(buffer, 0, BUFFER_SIZE);
                if (bytesRead > 0)
                    destination.Write(buffer, 0, bytesRead);
                bytesCopied += bytesRead;
            }
            while (bytesRead > 0);

            return bytesCopied;
        }

РЕДАКТИРОВАНИЕ 2:

Я заметил, что когда файл загружается с использованием метода blob.UploadText (), он работает нормально, но когда BLOB-объект загружается с использованием метода OpenWrite, как это сделано вВ следующем примере кода метод OpenRead читает только 4194304 байта (4 МБ).

using(var input = File.OpenRead(@"C:\testFile.txt")) //5000000 bytes
using (var output = blob.OpenWrite())
{
       input.CopyTo(output);
}

РЕДАКТИРОВАТЬ 3:

Полный код, который создает проблему на моем конце.

 static void Main(string[] args)
    {
        var blobContainer = GetContainer("tier1");
        blobContainer.CreateIfNotExist();

        var containerPermissions = new BlobContainerPermissions();
        containerPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;
        blobContainer.SetPermissions(containerPermissions);
        var blob = blobContainer.GetBlobReference("testfileWithOpenWrite1.txt");

        using (var input = File.OpenRead(@"C:\testFile.txt")) //5000000 bytes
        using (var output = blob.OpenWrite(new BlobRequestOptions()))
            input.CopyTo(output);

        Console.WriteLine("uploaded");

        int bytesDownloaded = 0;
        byte[] buffer = new byte[65536];

        using (BlobStream bs = blob.OpenRead())
        {
            int chunkLength;
            do
            {
                chunkLength = bs.Read(buffer, 0, buffer.Length);
                bytesDownloaded += chunkLength;
            } while (chunkLength > 0);
        }

        Console.WriteLine(bytesDownloaded);
    }

    public static int CopyTo(this Stream source, Stream destination)
    {
        int BUFFER_SIZE = 65536;
        byte[] buffer = new byte[BUFFER_SIZE];
        int bytesRead;
        int bytesCopied = 0;

        do
        {
            bytesRead = source.Read(buffer, 0, BUFFER_SIZE);
            if (bytesRead > 0)
                destination.Write(buffer, 0, bytesRead);
            bytesCopied += bytesRead;
        }
        while (bytesRead > 0);

        return bytesCopied;
    }

РЕДАКТИРОВАТЬ 4 - Заключение:

Это, вероятно, ошибка в Microsoft.WindowsAzure.StorageClient.dll (сборочная версия 6.0.6002.17043), которая поставляется с SDKv1.2.Он работает с последней версией Microsoft.WindowsAzure.StorageClient.dll (сборочная версия 6.0.6002.18312 - SDK v1.4).

Спасибо, smarx:)

1 Ответ

5 голосов
/ 02 августа 2011

Я не могу воспроизвести то, что вы видите. Вещи, кажется, работают как ожидалось:

static void Main(string[] args)
{
    // I also tried a real cloud storage account. Same result.
    var container = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudBlobClient().GetContainerReference("testcontainer");
    container.CreateIfNotExist();

    var blob = container.GetBlobReference("testblob.txt");

    blob.UploadText(new String('x', 5000000));

    var source = blob.OpenRead();

    int BUFFER_SIZE = 4000000;
    byte[] buffer = new byte[BUFFER_SIZE];
    int bytesRead;
    int bytesCopied = 0;
    do
    {
        bytesRead = source.Read(buffer, 0, BUFFER_SIZE);
        bytesCopied += bytesRead;
    } while (bytesRead > 0);

    Console.WriteLine(bytesCopied); // prints 5000000
}

EDIT:

Я также (в ответ на отредактированный вопрос) теперь попытался загрузить BLOB-объект с помощью OpenWrite, и результат тот же. (Я получаю полный блоб обратно.) Я использовал этот код вместо blob.UploadText (...):

using (var input = File.OpenRead(@"testblob.txt")) //5000000 bytes
using (var output = blob.OpenWrite())
{
    input.CopyTo(output);
}

Конечная строка печати по-прежнему печатает 5000000.

РЕДАКТИРОВАТЬ 2:

Это становится немного утомительно. Изменение BUFFER_SIZE на 65536 ничего не изменило. Результаты все еще кажутся мне правильными. Вот мое полное приложение для сравнения:

static void Main(string[] args)
{
    // I also tried a real cloud storage account. Same result.
    var container = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudBlobClient().GetContainerReference("testcontainer");
    container.CreateIfNotExist();

    var blob = container.GetBlobReference("testblob.txt");

    using (var input = File.OpenRead(@"testblob.txt")) //5000000 bytes
    using (var output = blob.OpenWrite())
    {
        input.CopyTo(output);
    }

    var source = blob.OpenRead();

    int BUFFER_SIZE = 65536;
    byte[] buffer = new byte[BUFFER_SIZE];
    int bytesRead;
    int bytesCopied = 0;
    do
    {
        bytesRead = source.Read(buffer, 0, BUFFER_SIZE);
        bytesCopied += bytesRead;
    } while (bytesRead > 0);

    Console.WriteLine(bytesCopied); // prints 5000000
}
...