如何在文件开始流式传输到浏览器后清除Azure本地存储中的文件和目录?

问题描述:

背景:我正在使用Azure本地存储。这应该被视为“易失性”存储。首先,我创建的文件目录&在Web角色实例上存在多长时间(在我的情况下有2个)?如果我在每个用户完成之后不对这些文件/目录进行清理,我是否需要担心存储用完?我正在做的是我从一个单独的服务中提取多个文件,将它们存储在Azure本地存储中,将它们压缩成一个zip文件并存储该zip文件,然后最终将该zip文件传输到浏览器。如何在文件开始流式传输到浏览器后清除Azure本地存储中的文件和目录?

问题:这一切都运作精美,除了一个小呃逆。该文件似乎异步流向浏览器。因此,当我尝试从Azure本地存储中删除压缩文件后,会发生异常,因为它仍在流式传输到浏览器。在文件完全流式传输到浏览器后,强制删除过程发生的最佳方法是什么?

这里是我的代码:

   using (Service.Company.ServiceProvider CONNECT = new eZ.Service.CompanyConnect.ServiceProvider()) 
      { 
       // Iterate through all of the files chosen 
       foreach (Uri fileId in fileIds) 
       { 
        // Get the int file id value from the uri 
        System.Text.RegularExpressions.Regex rex = new System.Text.RegularExpressions.Regex(@"e[B|b]://[^\/]*/\d*/(\d*)"); 
        string id_str = rex.Match(fileId.ToString()).Groups[1].Value; 
        int id = int.Parse(id_str); 

        // Get the file object from eB service from the file id passed in 
        eZ.Data.File f = new eZ.Data.File(CONNECT.eZSession, id); 
        f.Retrieve("Header; Repositories"); 

        string _fileName = f.Name; 

        try 
        { 
         using (MemoryStream stream = new MemoryStream()) 
         { 
          f.ContentData = new eZ.ContentData.File(f, stream); 

          // After the ContentData is created, hook into the event 
          f.ContentData.TransferProgressed += (sender, e) => { Console.WriteLine(e.Percentage); }; 

          // Now do the transfer, the event will fire as blocks of data is read 
          int bytesRead; 
          f.ContentData.OpenRead(); 
          // Open the Azure Local Storage file stream 
          using (azure_file_stream = File.OpenWrite(curr_user_path + _fileName)) 
          { 
           while ((bytesRead = f.ContentData.Read()) > 0) 
           { 
            // Write the chunk to azure local storage 
            byte[] buffer = stream.GetBuffer(); 
            azure_file_stream.Write(buffer, 0, bytesRead); 
            stream.Position = 0; 
           } 
          } 
         } 
        } 
        catch (Exception e) 
        { 
         throw e; 
         //Console.WriteLine("The following error occurred: " + e); 
        } 
        finally 
        { 
         f.ContentData.Close(); 
        } 
       } // end of foreach block 

      } // end of eB using block 

      string sevenZipDllPath = Path.Combine(Utilities.GetCurrentAssemblyPath(), "7z.dll"); 
      Global.logger.Info(string.Format("sevenZipDllPath: {0}", sevenZipDllPath)); 
      SevenZipCompressor.SetLibraryPath(sevenZipDllPath); 

      var compressor = new SevenZipCompressor 
      { 
       ArchiveFormat = OutArchiveFormat.Zip, 
       CompressionLevel = CompressionLevel.Fast 
      }; 

      // Compress the user directory 
      compressor.CompressDirectory(webRoleAzureStorage.RootPath + curr_user_directory, curr_user_package_path + "Package.zip"); 

      // stream Package.zip to the browser 
      httpResponse.BufferOutput = false; 
      httpResponse.ContentType = Utilities.GetMIMEType("BigStuff3.mp4"); 
      httpResponse.AppendHeader("content-disposition", "attachment; filename=Package.zip"); 

      azure_file_stream = File.OpenRead(curr_user_package_path + "Package.zip"); 
      azure_file_stream.CopyTo(httpResponse.OutputStream); 
      httpResponse.End(); 

      // Azure Local Storage cleanup 
      foreach (FileInfo file in user_directory.GetFiles()) 
      { 
       file.Delete(); 
      } 
      foreach (FileInfo file in package_directory.GetFiles()) 
      { 
       file.Delete(); 
      } 
      user_directory.Delete(); 
      package_directory.Delete(); 
     } 

你能简单地运行他们的创作经过一天的发言权清理文件,机器上的工作吗?这可能与任务计划程序中的批处理文件或从WebRole.cs启动的单独线程一样简单。 你甚至可以使用AzureWatch为自动重新图像的情况下,如果在本地空间低于某个阈值

+0

感谢您的意见。我一定会看看这个AzureWatch。 – TheDude

你能放置文件(尤指用户下载最终的压缩之一。)在Windows Azure的Blob存储?该文件可以公开,或创建一个共享访问签名,以便只有您提供该URL的人可以下载它。将文件放置在blob存储器中进行下载可以缓解Web服务器上的一些压力。

+0

这实际上是首选的长期解决方案。这只是暂时的解决方案。 – TheDude