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);
}

 

posted @ 2017-04-11 11:07  公羊天纵  阅读(791)  评论(0编辑  收藏  举报