2013-03-25 77 views
3

这个想法很简单,我正在创建一项服务,用户可以在另一个网站上放置一个文件的直接链接,我的程序将打开一个流到该远程服务器并开始以字节读取文件然后将每个读取的字节返回给用户。恢复下载

到目前为止,我设法让该工作,这里是我的代码

public void Index() 
    { 
     //Create a stream for the file 
     Stream stream = null; 

     //This controls how many bytes to read at a time and send to the client 
     int bytesToRead = 10000; //10000 

     // Buffer to read bytes in chunk size specified above 
     byte[] buffer = new Byte[bytesToRead]; 

     // The number of bytes read 
     try 
     { 
      //Create a WebRequest to get the file 
      HttpWebRequest fileReq = (HttpWebRequest)HttpWebRequest.Create("http://SOME-OTHER-SERVER.com/File.rar"); 


      //Create a response for this request 
      HttpWebResponse fileResp = (HttpWebResponse)fileReq.GetResponse(); 


      if (fileReq.ContentLength > 0) 
       fileResp.ContentLength = fileReq.ContentLength; 

      //Get the Stream returned from the response 
      stream = fileResp.GetResponseStream(); 

      // prepare the response to the client. resp is the client Response 
      var resp = HttpContext.Response; 

      //Indicate the type of data being sent 
      resp.ContentType = "application/octet-stream"; 

      //Name the file 
      resp.AddHeader("Content-Disposition", "attachment; filename=\"" + "fle.rar" + "\""); 
      resp.AddHeader("Content-Length", (fileResp.ContentLength).ToString()); 

      int length; 
      do 
      { 
       // Verify that the client is connected. 
       if (resp.IsClientConnected) 
       { 
        // Read data into the buffer. 
        length = stream.Read(buffer, 0, bytesToRead); 

        // and write it out to the response's output stream 
        resp.OutputStream.Write(buffer, 0, length); 

        // Flush the data 
        resp.Flush(); 

        //Clear the buffer 
        buffer = new Byte[bytesToRead]; 
       } 
       else 
       { 
        // cancel the download if client has disconnected 
        length = -1; 
       } 
      } while (length > 0); //Repeat until no data is read 
     } 
     finally 
     { 
      if (stream != null) 
      { 
       //Close the input stream 
       stream.Close(); 
      } 
     } 
    } 

当我去到我的网页它下载完美,但问题是,如果我停止下载,不会再恢复。

我搜索了这个问题,发现有一个头文件“Accept-Ranges”必须在连接中定义以支持简历。

所以我添加了标题,但没有工作。

回答

13

处理Range Requests比这稍微复杂一些。一般来说,您需要在请求中处理RangeIf-Range标题,并且以Content-Range,DateETagContent-Location标题响应206部分内容

文章Range Requests in ASP.NET MVC – RangeFileResult详细描述了如何创建一个ASP.NET MVC ActionResult范围请求的支持。

在你的情况下,你还必须检查对方(你使用的那一个是fileReq)是否支持范围请求。如果是,你可以只请求所需的部分(并且最好将其缓存在本地),但如果不是,则需要获取整个文件并寻找适当的位置(在这种情况下,你明确想要本地缓存场景)。

+0

非常感谢,这是一个完美的答案:) – BOSS 2013-10-15 13:12:54