zoukankan      html  css  js  c++  java
  • Azure存储上传下载(断点续传)

    最近有一个客户需要将文件系统(VM搭建)迁移到Azure存储上,对于Azure存储这里就不多做介绍,但是该客户由于网络原因下载文件的时候经常出现上传中断,所以想在Azure 存储上实现下载的断点续传。下面我就用C#代码实现在Azure存储上下载断点续传,这里只提供一个示例,具体应用需结合业务调整。

    由于在前面几篇Blog收到一些批评和建议,这里我们的示例代码也尽量符合实际开发规范。

    首先配置Azure存储信息

    下载断点续传

    //存储连接字符串
    static string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
    //存储容器名称
    static string containerName = ConfigurationManager.AppSettings["StorageContainer"];
    //一次下载数据块大小,这里我设置的是2MB
    static int bufferSize = 1024 * 1024 * 2;
    static void Main(string[] args)
    {
          //这里就直接指定一个存储中的Blob文件
          string fileName = "aspnet-core.pdf";
          DownloadBlockBlobBreakPoint(containerName, fileName);
          Console.WriteLine("文件下载成功...");
          Console.ReadKey();
    }
    
    /// <summary>
    /// 文件下载(断点续传)
    /// </summary>
    /// <param name="container"></param>
    /// <param name="fileName"></param>
    private static void DownloadBlockBlobBreakPoint(string container,string fileName)
    {
           //这里我没有返回文件流或者byte数组,而是直接在此接口中直接写文件,主要是图方便
           //每一个存储中的Blob文件都有一个对应的记录该文件下载到哪一位置的文本文件
           string flagFile = Path.GetFileNameWithoutExtension(fileName) + ".txt";
           CloudBlockBlob blockBlob = GetBlockBlob(container, fileName);
           byte[] buffer = new byte[bufferSize];
           blockBlob.FetchAttributes();
           long blobSize = blockBlob.Properties.Length;
           int blobCount = (int)(blobSize / bufferSize) + 1;
           int currentCount = 0;
           if (!File.Exists(flagFile))
           {
                FileStream fs = File.Create(flagFile);
                fs.Close();
                fs.Dispose();
            }else
            {
                 string[] ids = File.ReadAllLines(flagFile);
                 currentCount = ids.Length;
            }
          for (int i = currentCount; i < blobCount; i++)
          {
               int totalNumber = blockBlob.DownloadRangeToByteArray(buffer, 0, currentCount * bufferSize, bufferSize);
                Console.WriteLine(i.ToString());
                if (totalNumber > 0)
                {
                    using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.Write))
                    {
                        fs.Write(buffer, 0, buffer.Length);
                     }
                     File.AppendAllLines(flagFile, new List<string>() { Guid.NewGuid().ToString() });
                      currentCount++;
                  }
                else
                {
                    break;
                }
          }
    }
    
    /// <summary>
    /// 获取Azure存储中指定的Blob文件
    /// </summary>
    /// <param name="container"></param>
    /// <param name="fileName"></param>
    /// <returns></returns>
    private static CloudBlockBlob GetBlockBlob(string container, string fileName)
    {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer blobContainer = blobClient.GetContainerReference(container);
            blobContainer.CreateIfNotExists();
            CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference(fileName);
            return blockBlob;
    }
    

    虽然客户只提出了下载断点续传,但是要写就索性写完整一点,下面我把上传断点续传也实现了。

    /// <summary>
    /// 文件上传(断点续传)
    /// </summary>
    /// <param name="container"></param>
    /// <param name="path"></param>
    private static void UploadBlockBlobBreakPoint(string container,string path)
    {
        string flagFile = Path.GetFileNameWithoutExtension(path) + ".txt";
        string blobName = Path.GetFileName(path);
        CloudBlockBlob blockBlob = GetBlockBlob(container, blobName);
    
        byte[] buffer = new byte[bufferSize];
        int fileSize = File.ReadAllBytes(path).Length;
        int fileCount = fileSize / bufferSize + 1;
        int currentCount = 0;
        List<string> blobIdList = new List<string>();
        if (!File.Exists(flagFile))
        {
            FileStream fs = File.Create(flagFile);
            fs.Close();
            fs.Dispose();
        }
        else
        {
            string[] blobIds = File.ReadAllLines(flagFile);
            currentCount = blobIds.Length;
            blobIdList.AddRange(blobIds);
         }
    
         for (int i = currentCount ; i < fileCount; i++)
        {
            using (FileStream fs=new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read,bufferSize))
            {
                fs.Read(buffer, 0, buffer.Length);
    
             }
                    
             using(MemoryStream ms =new MemoryStream(buffer, 0, buffer.Length))
             {
                 string blobId = Convert.ToBase64String(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));
                 blockBlob.PutBlock(blobId, ms, null);
                 blobIdList.Add(blobId);
                 File.AppendAllLines(flagFile, new List<string>() { blobId });
              }
          }
          blockBlob.PutBlockList(blobIdList);
    }
  • 相关阅读:
    C#事件和委托的区别
    已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10()随机1~10
    如何搭建github+hexo博客-转
    ngRouter和ui-router区别
    JS数组追加数组采用push.apply的坑(转)
    vue中关于computed的一点理解
    simplify the life ECMAScript 5(ES5)中bind方法简介
    github使用-知乎的某小姐的一篇文章
    Jade 模板引擎使用
    玩转Nodejs日志管理log4js(转)
  • 原文地址:https://www.cnblogs.com/rampb/p/6692629.html
Copyright © 2011-2022 走看看