【问题标题】:CloudBlob.OpenRead() is not reading all dataCloudBlob.OpenRead() 未读取所有数据
【发布时间】:2011-08-02 12:02:38
【问题描述】:

使用 Windows Azure 存储客户端库,CloudBlob.OpenRead() 方法仅读取 4 mb 的数据。如何使用 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() 方法上传文件时,它可以正常工作,但是当按照以下代码示例使用 OpenWrite 方法上传 blob 时,OpenRead 方法仅读取 4194304 字节 (4 mb)。

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 - 结论:

这可能是 SDK v1.2 附带的 Microsoft.WindowsAzure.StorageClient.dll(程序集版本 6.0.6002.17043)中的一个错误。它适用于最新的 Microsoft.WindowsAzure.StorageClient.dll(程序集版本 6.0.6002.18312 - SDK v1.4)。

谢谢 smarx :)

【问题讨论】:

  • 请在调用OpenRead 后添加显示您对stream 执行操作的代码。
  • 您确定 blob 存储中的文件大于 4MB?

标签: c# .net azure


【解决方案1】:

我无法重现您所看到的内容。事情似乎按预期工作:

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
}

编辑:

我现在也(针对已编辑的问题)尝试使用 OpenWrite 上传 blob,结果是一样的。 (我得到了完整的 blob。)我用这段代码代替了 blob.UploadText(...):

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

最后的 WriteLine 仍然打印 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
}

【讨论】:

  • 是的,当我们使用 UploadText 方法时它可以工作。但是当使用 OpenWrite 方法编写时,它只能读取 4 mb 的数据。这似乎是某种分页概念。
  • 答案已编辑。我仍然无法重现该问题。你能分享一个产生错误的完整的、正常运行的程序吗?
  • 你知道吗,当我将程序中的 BUFFER_SIZE 设置为 4000000 时,它起作用了 :)。我的程序有 BUFFER_SIZE=65536 即 64KB。如果将 BUFFER_SIZE 设置为 65536 甚至 2000000 和 3000000,它可以在您的程序中重现。我无法更改 BUFFER_SIZE!
  • 再次编辑了我的回复。我没有发现更改 BUFFER_SIZE 的值有效果。请分享一个产生错误的完整、正常运行的程序。
  • 好吧,我想我想通了。问题出在 SDK v1.2 附带的 StorageClient.dll 上。我已经下载了最新的 SDk,它开始正常工作。一旦我切换回旧 dll,它就会再次出现。感谢 smarx 容忍我 :)。我接受您的回答是因为您让我认为问题可能出在我正在使用的 StorageClient.dll 上。
猜你喜欢
  • 2014-09-15
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 2012-09-14
  • 2017-10-25
  • 2020-08-15
  • 2016-07-10
相关资源
最近更新 更多