【问题标题】:Azure blob file got corrupted post uploading file using UploadFromStreamAsync使用 UploadFromStreamAsync 上传文件后 Azure Blob 文件已损坏
【发布时间】:2020-01-14 00:25:17
【问题描述】:

我尝试使用以下代码将文件上传到 azure blob 容器,但上传的文件已损坏。

 public async void UploadFile(Stream memoryStream, string fileName, string containerName)
    {
        try
        {
             memoryStream.Position = 0;
            CloudBlockBlob file = GetBlockBlobContainer(containerName).GetBlockBlobReference(fileName);
            file.Metadata["FileType"] = Path.GetExtension(fileName);
            file.Metadata["Name"] = fileName;
           await file.UploadFromStreamAsync(memoryStream).ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

我该如何解决。

无法打开使用上述代码上传到 blob 的 excel 文件。

错误:

     Stream streamData= ConvertDataSetToByteArray(sourceTable); // sourceTable is the DataTable
                     streamData.Position = 0;

UploadFile(streamData,'ABCD.xlsx','sampleBlobContainer'); //calling logic to upload stream to blob

       private Stream ConvertDataSetToByteArray(DataTable dataTable)
            {

                StringBuilder sb = new StringBuilder();
                IEnumerable<string> columnNames = dataTable.Columns.Cast<DataColumn>().
                                                  Select(column => column.ColumnName);
                sb.AppendLine(string.Join(",", columnNames));

                foreach (DataRow row in dataTable.Rows)
                {
                    IEnumerable<string> fields = row.ItemArray.Select(field => (field.ToString()));
                    sb.AppendLine(string.Join(",", fields));
                }

                var myByteArray = System.Text.Encoding.UTF8.GetBytes(sb.ToString());

                var streamData = new MemoryStream(myByteArray);

                return streamData;
            }

【问题讨论】:

  • 您说文件已损坏是什么意思?它不可读还是什么?你能说得更具体点吗?
  • 请检查您的内存流转换部分是否有误。
  • got corrupted 是什么意思? MemoryStream 来自哪里,它包含什么?你确定它的内容没问题?如果您上传损坏的数据,结果将是一个损坏的文件。
  • 用损坏的文件截图更新问题
  • @chandrasekhar 您的意思是您将 .xlsx 文件上传到 azure blob 存储但下载后损坏了吗?

标签: c# azure asp.net-core azure-blob-storage


【解决方案1】:

您上面的代码会创建一个 .csv 文件,而不是一个 .xlsx 文件。您可以通过创建类似于您的代码构建的内容来轻松测试这一点,例如:

然后,如果您将其重命名为 .xlsx,以复制您所做的,您会得到:

你有两个解决方案:

  1. 您需要构建一个实际的 .xlsx 文件,例如,您可以使用 https://github.com/JanKallman/EPPlus 包来完成此操作

  1. 您需要将文件另存为 .csv,因为它确实如此。

您将其上传到 azure blob 存储的事实在这里完全无关紧要 - 上传没有问题。

【讨论】:

  • 我们不能不使用任何包直接在blob中创建xlsx文件,而不是从DataTable流创建csv。
【解决方案2】:

由于流是在此方法之外实例化的,我假设文件在那里处理并添加到流中,但是,在这里您将流的位置返回为 0,从而使文件无效。

【讨论】:

  • 我尝试将位置添加到 0,即使在流根位置,即使遇到同样的问题
【解决方案3】:

首先,您确定文件已损坏吗?将MemoryStream 内容和博客保存到本地文件并进行比较。您还可以将 MemoryStream 内容保存到文件并使用UploadFromFileAsync

要检查实际损坏情况,您应该提前计算内容的 MD5 哈希值,并将其与上传后的 blob 哈希值进行比较。

要计算流的 MD5 哈希,请使用 ComputeHash

var hasher=MD5.Create();
 memoryStream.Position = 0;
var originalHash=Convert.ToBase64String(hasher.ComputeHash(memoryStream));

要让客户端计算 blob,您需要在上传时设置 BlobRequestOptions.StoreBlobContentMD5 选项:

memoryStream.Position = 0;
var options = new BlobRequestOptions()
        {
            StoreBlobContentMD5 = testMd5
        };
await file.UploadFromStreamAsync(memoryStream,null,options,null).ConfigureAwait(false);

要检索和检查上传的哈希,请使用 FetchAttributesFetchAttributesAsync 并将 BlobProperties.ContentMD5 值与原始值进行比较:

file.FetchAttributes();
var blobHash=file.Properties.ContentMD5;
if (blobHash != originalHash)
{
   //Ouch! Retry perhaps?
}

【讨论】:

    【解决方案4】:

    您的方法似乎没有致命问题。我猜你的 Stream 转换部分出错了。

    这是我的代码:

    using System;
    using System.IO;
    using Microsoft.WindowsAzure.Storage;
    
    namespace ConsoleApp7
    {
        class Program
        {
            public static class Util
            {
                public async static void UploadFile(Stream memoryStream, string fileName, string containerName)
                {
                    memoryStream.Position = 0;
                    var storageAccount = CloudStorageAccount.Parse("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    var blockBlob = storageAccount.CreateCloudBlobClient()
                        .GetContainerReference(containerName)
                        .GetBlockBlobReference(fileName);
                    blockBlob.UploadFromStreamAsync(memoryStream);
                }
            }
            static void Main(string[] args)
            {
                //Open the file
                FileStream fileStream = new FileStream("C:\\Users\\bowmanzh\\Desktop\\Book1.xlsx", FileMode.Open);
    
                //Read the byte[] of File
                byte[] bytes = new byte[fileStream.Length];
                fileStream.Read(bytes,0,bytes.Length);
                fileStream.Close();
    
                //turn from byte[] to Stream
                Stream stream = new MemoryStream(bytes);
    
                Util.UploadFile(stream,"Book2.xlsx","test");
                Console.WriteLine("Hello World!");
                Console.ReadLine();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-12
      • 2020-04-05
      • 2018-12-29
      • 1970-01-01
      • 2017-08-29
      • 2017-06-27
      • 2013-10-24
      • 2018-06-21
      相关资源
      最近更新 更多