当前位置: 首页 > 知识库问答 >
问题:

在Azure Blob存储上上传大文件时"流太长"

匡祖鹤
2023-03-14

我试图将大文件(4Gb)上传到Azure Blob存储,但失败了。根据本文(https://docs.microsoft.com/en-us/azure/storage/storage-dotnet-how-to-use-blobs),这是我的代码:

CloudBlobContainer blobContainer = blobClient.GetContainerReference("my-container-name");
blobContainer.CreateIfNotExistsAsync().Wait();
CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference("blob-name");
await blockBlob.UploadFromFileAsync("C:\test.avi");

但我犯了这个错误

信息:流太长了<来源:系统。私有的CoreLib
StackTrace:at系统。伊奥。记忆之流。在Microsoft上写入(字节[]缓冲区、Int32偏移量、Int32计数)。WindowsAzure。存储斑点。BlobWriteStream。d__5。C:\Program Files(x86)\Jenkins\workspace\release\u dotnet\u master\Lib\WindowsRuntime\Blob\BlobWriteStream中的MoveNext()。cs:第144行——来自引发异常的前一个位置的堆栈结束跟踪——在系统中。运行时。编译器服务。任务等待者。系统中的ThrowForNonSuccess(任务)。运行时。编译器服务。任务等待者。HandleNonSuccessAndDebuggerNotification(任务)在Microsoft。WindowsAzure。存储果心Util。流光延伸。d__1`1。C:\Program Files(x86)\Jenkins\workspace\release\u dotnet\u master\Lib\Common\Core\Util\StreamExtensions中的MoveNext()。cs:第308行——来自引发异常的前一个位置的堆栈结束跟踪——在系统上。运行时。编译器服务。任务等待者。系统中的ThrowForNonSuccess(任务)。运行时。编译器服务。任务等待者。HandleNonSuccessAndDebuggerNotification(任务)在Microsoft。WindowsAzure。存储斑点。云块。

根据本文(https://www.simple-talk.com/cloud/platform-as-a-service/azure-blob-storage-part-4-uploading-large-blobs/)我尝试为大文件添加更多选项。这是我的新代码:

TimeSpan backOffPeriod = TimeSpan.FromSeconds(2);
int retryCount = 1;
BlobRequestOptions bro = new BlobRequestOptions()
{
    //If the file to upload is more than 67Mo, we send it in multiple parts
    SingleBlobUploadThresholdInBytes = 67108864, //67Mo (maximum)
    //Number of threads used to send data
    ParallelOperationThreadCount = 1,
    //If the block fail, we retry once (retryCount) after 2 seconds (backOffPeriod)
    RetryPolicy = new ExponentialRetry(backOffPeriod, retryCount),
};
blobClient.DefaultRequestOptions = bro;
CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference("blob-name");
//If the file is sended in multiple parts, theses parts size are 4Mo
blockBlob.StreamWriteSizeInBytes = 4194304; //4Mo (maximum)
await blockBlob.UploadFromFileAsync("C:\test.avi");

但是我又犯了同样的错误(Stream太长了)。

我在微软。WindowsAzure。存储库中发现,函数“上传文件同步”使用使用MemoryStream的“上传流同步”。我想我的错误来自MemoryStream,但它在Blob存储文章中写道,Blob的最大大小为195Gb。那么我应该如何使用它呢?

我使用微软。WindowsAzure。存储版本7.2.1

谢谢

.

更新1:多亏了Tom Sun和Lu肇星,我尝试了使用微软。蔚蓝色的存储数据移动<遗憾的是,“TransferManager.UploadAsync”函数出现错误。我试着用谷歌搜索,但什么都没有<有什么想法吗?

这是我的代码:

 string storageConnectionString = "myStorageConnectionString";
   string filePath = @"C:\LargeFile.avi";
   string blobName = "large_file.avi";

    CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
    CloudBlobClient blobClient = account.CreateCloudBlobClient();
    CloudBlobContainer blobContainer = blobClient.GetContainerReference("mycontainer");
    blobContainer.CreateIfNotExists();

   CloudBlockBlob destBlob = blobContainer.GetBlockBlobReference(blobName);
    // Setup the number of the concurrent operations
    TransferManager.Configurations.ParallelOperations = 64;

    // Setup the transfer context and track the upload progress
    var context = new SingleTransferContext();
    UploadOptions uploadOptions = new UploadOptions
    {
        DestinationAccessCondition = AccessCondition.GenerateIfExistsCondition()
    };
    context.ProgressHandler = new Progress<TransferStatus>(progress =>
    {
        Console.WriteLine("Bytes uploaded: {0}", progress.BytesTransferred);
    });

    // Upload a local blob
    TransferManager.UploadAsync(filePath, destBlob, uploadOptions, context, CancellationToken.None).Wait();

这是错误:
消息:发生了一个或多个错误。(传输失败:值“*”的格式无效..)<来源:系统。私有的CoreLib
StackTrace:

在系统中。穿线。任务。任务系统中的ThrowifeException(布尔includeTaskCanceledException)。穿线。任务。任务在系统上等待(Int32毫秒,CancellationToken CancellationToken)。穿线。任务。任务在我公司等着。AzureServices。斑点。女服务员。d__7。C:\MyProjectSource\MyCompany中的MoveNext()。AzureServices\Blob\BlobService。cs:第96行——来自引发异常的前一个位置的堆栈结束跟踪——在系统上。运行时。编译器服务。任务等待者。系统中的ThrowForNonSuccess(任务)。运行时。编译器服务。任务等待者。HandleNonSuccessAndDebuggerNotification(任务任务)在系统中。运行时。编译器服务。任务等待者。GetResult()
在MyCompany。AzureServices。斑点。我的项目。RecordBlobService。

内部异常:
消息:传输失败:值“*”的格式无效<来源:微软。WindowsAzure。存储数据移动
堆栈跟踪:

在Microsoft。WindowsAzure。存储。数据运动。TransferScheduler。d__22。MoveNext()在C:\本地\Jenkins\作业\DM_Hotfix\工作空间\lib\TransferScheduler.cs:第214行-从以前抛出异常的位置开始的堆栈跟踪结束-在System。运行时。CompilerServices。TaskAwaiter。ThrowFornon成功(任务任务)在System。运行时。CompilerServices。TaskAwaiter。在Microsoft。WindowsAzure。存储。数据运动。SingleObjecttrans。d__7。MoveNext()在C:\本地\Jenkins\作业\DM_Hotfix\工作空间\lib\TransferJobs\SingleObjectTransfer.cs:第226行-从以前抛出异常的位置开始的堆栈跟踪结束-在System。运行时。CompilerServices。TaskAwaiter。ThrowFornon成功(任务任务)在System。运行时。CompilerServices。TaskAwaiter。Handlenon成功AndDebuggerNo一人C中的MoveNext():\本地\Jenkins\作业\DM_Hotfix\工作空间\lib\TransferManager.cs: line 1263

下一个内部异常:
消息:值“*”的格式无效<来源:微软。WindowsAzure。存储数据移动
堆栈跟踪:

在微软。WindowsAzure。存储数据移动。转移控制器。BlockBlobWriter。C:\Local\Jenkins\jobs\DM_Hotfix\workspace\lib\TransferControllers\TransferWriters\BlockBlobWriter中的HandleFetchAttributesResult(例外e)。政务司司长:微软196行。WindowsAzure。存储数据移动。转移控制器。BlockBlobWriter。18岁。C:\Local\Jenkins\jobs\DM_Hotfix\workspace\lib\TransferControllers\TransferWriters\BlockBlobWriter中的MoveNext()。cs:第157行——来自引发异常的前一个位置的堆栈结束跟踪——在系统中。运行时。编译器服务。任务等待者。系统中的ThrowForNonSuccess(任务)。运行时。编译器服务。任务等待者。HandleNonSuccessAndDebuggerNotification(任务)在Microsoft。WindowsAzure。存储数据移动。转移控制器。BlockBlobWriter。d__16。C:\Local\Jenkins\jobs\DM_Hotfix\workspace\lib\TransferControllers\TransferWriters\BlockBlobWriter中的MoveNext()。cs:第83行——来自引发异常的前一个位置的堆栈结束跟踪——在系统上。运行时。编译器服务。任务等待者。系统中的ThrowForNonSuccess(任务)。运行时。编译器服务。任务等待者。HandleNonSuccessAndDebuggerNotification(任务)在Microsoft。WindowsAzure。存储数据移动。转移控制器。同步传输控制器。d__13。C:\Local\Jenkins\jobs\DM_Hotfix\workspace\lib\TransferControllers\SyncTransferController中的MoveNext()。cs:第81行——来自引发异常的前一个位置的堆栈结束跟踪——在系统上。运行时。编译器服务。任务等待者。系统中的ThrowForNonSuccess(任务)。运行时。编译器服务。任务等待者。HandleNonSuccessAndDebuggerNotification(任务)在Microsoft。WindowsAzure。存储数据移动。转移控制器。转移控制基。d__33。C:\Local\Jenkins\jobs\DM_Hotfix\workspace\lib\TransferControllers\TransferControllerBase中的MoveNext()。cs:第178行——来自引发异常的前一个位置的堆栈结束跟踪——在系统上。运行时。编译器服务。任务等待者。系统中的ThrowForNonSuccess(任务)。运行时。编译器服务。任务等待者。HandleNonSuccessAndDebuggerNotification(任务)在Microsoft。WindowsAzure。存储数据移动。传送调度员。d__22。C:\Local\Jenkins\jobs\DM_Hotfix\workspace\lib\TransferScheduler中的MoveNext()。政务司司长:第208行

最后一个内部异常:
消息:值“*”的格式无效<来源:系统。网Http
StackTrace:

在System. Net. Http. Headers. HttpHeaderParser. ParseValue(字符串值,对象存储值,int32

最后我的project.json

  {
  "version": "1.0.0-*",

  "dependencies": {
    "Microsoft.Azure.DocumentDB.Core": "0.1.0-preview",
    "Microsoft.Azure.Storage.DataMovement": "0.4.1",
    "Microsoft.IdentityModel.Protocols": "2.0.0",
    "NETStandard.Library": "1.6.1",
    "MyProject.Data.Entities": "1.0.0-*",
    "MyProject.Settings": "1.0.0-*",
    "WindowsAzure.Storage": "7.2.1"
  },

  "frameworks": {   
    "netcoreapp1.0": {
      "imports": [
        "dnxcore50",
        "portable-net451+win8"
      ],
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.0-*"
        }
      }
    }
  }
}

谢谢你的帮助!

更新2(工作)

多亏了Tom Sun,这就是工作代码

string storageConnectionString = "myStorageConnectionString";
     CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
      CloudBlobClient blobClient = account.CreateCloudBlobClient();
      CloudBlobContainer blobContainer = blobClient.GetContainerReference("mycontainer");
      blobContainer.CreateIfNotExistsAsync().Wait();
      string sourcePath = @"C:\Tom\TestLargeFile.zip";
      CloudBlockBlob destBlob = blobContainer.GetBlockBlobReference("LargeFile.zip");
      // Setup the number of the concurrent operations
      TransferManager.Configurations.ParallelOperations = 64;
      // Setup the transfer context and track the upoload progress
      var context = new SingleTransferContext
      {
          ProgressHandler =
          new Progress<TransferStatus>(
               progress => { Console.WriteLine("Bytes uploaded: {0}", progress.BytesTransferred); })
       };
      // Upload a local blob
      TransferManager.UploadAsync(sourcePath, destBlob, null, context, CancellationToken.None).Wait();
      Console.WriteLine("Upload finished !");
      Console.ReadKey();

我还加上

ShouldOverwriteCallback = (source, destination) =>
               {
                   return true;
               },

SingleTransferContext中,如果blob已经存在,则覆盖它。

共有3个答案

齐高寒
2023-03-14

WindowsAzure的8.0版修复了最初的问题。存储

经佐
2023-03-14

我们正在Azure存储客户端库中积极研究这个问题。

请注意,由于UploadFromFileAsync()对于一个巨大的Blob来说不是一个可靠和高效的操作,我建议您考虑以下替代方案:

如果您可以接受命令行工具,可以尝试AzCopy,它能够以高性能传输Azure存储数据,并且可以暂停传输

如果您想以编程方式控制传输作业,请使用AzCopy的核心Azure Storage Data Movement Library。

池永长
2023-03-14

我们可以使用

    string storageConnectionString = "storage connection string";
    CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
    CloudBlobClient blobClient = account.CreateCloudBlobClient();
    CloudBlobContainer blobContainer = blobClient.GetContainerReference("mycontainer");
    blobContainer.CreateIfNotExists();
    string sourcePath = @"C:\Tom\TestLargeFile.zip";
    CloudBlockBlob destBlob = blobContainer.GetBlockBlobReference("LargeFile.zip");
    // Setup the number of the concurrent operations
    TransferManager.Configurations.ParallelOperations = 64;
    // Setup the transfer context and track the upoload progress

    var context = new SingleTransferContext();

    UploadOptions uploadOptions = new UploadOptions
    {
        DestinationAccessCondition = AccessCondition.GenerateIfExistsCondition()
    };
    context.ProgressHandler = new Progress<TransferStatus>(progress =>
    {
        Console.WriteLine("Bytes uploaded: {0}", progress.BytesTransferred);
    });
    // Upload a local blob
    TransferManager.UploadAsync(sourcePath, destBlob, uploadOptions,context, CancellationToken.None).Wait();

SDK信息请参考package.config文件

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net452" />
  <package id="Microsoft.Azure.Storage.DataMovement" version="0.4.1" targetFramework="net452" />
  <package id="Microsoft.Data.Edm" version="5.6.4" targetFramework="net452" />
  <package id="Microsoft.Data.OData" version="5.6.4" targetFramework="net452" />
  <package id="Microsoft.Data.Services.Client" version="5.6.4" targetFramework="net452" />
  <package id="Microsoft.WindowsAzure.ConfigurationManager" version="1.8.0.0" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="6.0.8" targetFramework="net452" />
  <package id="System.Spatial" version="5.6.4" targetFramework="net452" />
  <package id="WindowsAzure.Storage" version="7.2.1" targetFramework="net452" />
</packages>

检查从Azure门户上传的文件

更新:

. net核心项目代码:

     string storageConnectionString = "myStorageConnectionString";
     CloudStorageAccount account = CloudStorageAccount.Parse(storageConnectionString);
      CloudBlobClient blobClient = account.CreateCloudBlobClient();
      CloudBlobContainer blobContainer = blobClient.GetContainerReference("mycontainer");
      blobContainer.CreateIfNotExistsAsync().Wait();
      string sourcePath = @"C:\Tom\TestLargeFile.zip";
      CloudBlockBlob destBlob = blobContainer.GetBlockBlobReference("LargeFile.zip");
      // Setup the number of the concurrent operations
      TransferManager.Configurations.ParallelOperations = 64;
      // Setup the transfer context and track the upoload progress
      var context = new SingleTransferContext
      {
          ProgressHandler =
          new Progress<TransferStatus>(
               progress => { Console.WriteLine("Bytes uploaded: {0}", progress.BytesTransferred); })
       };
      // Upload a local blob
      TransferManager.UploadAsync(sourcePath, destBlob, null, context, CancellationToken.None).Wait();
      Console.WriteLine("Upload finished !");
      Console.ReadKey();
 类似资料:
  • 什么是 Firebase 存储上传文件大小限制?我在网站上找不到该信息。

  • 我正在使用Flutter开发一个Android应用程序。在我的应用程序中,有一个功能,用户可以从他们的设备上传图片。为了存储图像,我使用firebase云存储&下面是我用于将文件上传到firebase云存储的部分代码。 这里有3个相关的flutter插件,我正在使用,上面的帮助代码上传文件。 一切正常。不过,文件上传要花很多时间。几乎需要40-50秒才能完成步骤3()。有时也是1-半分钟。关于我的

  • 从spring boot Controller上传文件到谷歌云存储。请提供我一个代码。 到目前为止,我得到了这样一个代码

  • 我正在寻找将文件上传到存储桶的 。这是因为我有一个匿名用户,某种程度上是一个公开的API密钥。稍后我将实现每个用户的ACL,但现在我只需要它来工作/上传。 现在,我在Amazon Cloud上也做了类似的工作,有一个简单的基于jQuery的小部件,可以上传文件,我只需要输入它们的和bucket名称(很遗憾,这是在中)。 只要一个简单的

  • 接口说明 上传文件(临时存放) 如需调用,请访问 开发者文档 来查看详细的接口使用说明 该接口仅开放给已获取SDK的开发者 API地址 POST /wish3dearth/api/scene/v1.0.0/uploadTempFile 是否需要登录 是 请求字段说明 参数 类型 请求类型 是否必须 说明 token string header 是 当前登录用户的TOKEN sceneId stri

  • 接口说明 上传文件(临时存放) 如需调用,请访问 开发者文档 来查看详细的接口使用说明 该接口仅开放给已获取SDK的开发者 如开启https功能,请求地址的协议应改为https,如:https://www.example.com/wish3dearth/api/access/v1.0.0/getLicenseInfo API地址 POST /wish3dearth/api/scene/v1.0.0