【问题标题】:c# Dropbox RestSharp download file to streamc# Dropbox RestSharp 下载文件到流式传输
【发布时间】:2015-12-09 15:55:25
【问题描述】:

我有一个“ASP.NET”控制台应用程序,并为 Dropbox 使用“RestSharp”客户端。

我使用此代码下载文件:

 var baseUrl = "https://content.dropboxapi.com";

 var client = new RestClient(baseUrl);
 client.Authenticator = OAuth1Authenticator.ForRequestToken(mc_apiKey, mc_appsecret);

 RestRequest request = new RestRequest(string.Format("/{0}/files/auto", mc_version), Method.GET);

 client.Authenticator = OAuth1Authenticator.ForProtectedResource(mc_apiKey, mc_appsecret, accessToken.Token, accessToken.Secret);
 request.AddParameter("path", path);

 var responseAccount = client.Execute(request);
 var fileString = responseAccount.Content;
 byte[] b1 = System.Text.Encoding.UTF8.GetBytes (fileString);

当调用client.Execute(request)时,整个文件被加载到内存中,所以当我在 Dropbox 中有一个非常大的文件时,程序会崩溃。

我需要让文件流式传输而不使用client.DownloadData(request).SaveAs(path) 下载到本地存储。

我需要能够分块流式传输文件。

【问题讨论】:

    标签: c# dropbox dropbox-api restsharp


    【解决方案1】:

    你可以像这样设置 request.ResponseWriter :

      var baseUrl = "https://content.dropboxapi.com";
    
      var client = new RestClient(baseUrl);
      client.Authenticator = OAuth1Authenticator.ForRequestToken(mc_apiKey,mc_appsecret);
    
      RestRequest request = new RestRequest(string.Format("/{0}/files/auto", mc_version), Method.GET);
    
      client.Authenticator = OAuth1Authenticator.ForProtectedResource(mc_apiKey, mc_appsecret, accessToken.Token, accessToken.Secret);
      request.AddParameter("path", path);
    
      string tempFile = Path.GetTempFileName();
      using(var stream = File.Create(tempFile, 1024, FileOptions.DeleteOnClose ))
      {
        request.ResponseWriter = (responseStream) => responseStream.CopyTo(stream);
        var response = client.DownloadData(request);
      }
    

    您可以从文档here 中查看示例

    【讨论】:

    • 感谢@swestner 的回复。但我需要获取流而不是将文件保存在 temp 中。这将增加我的磁盘大小。如果我从 dropbox 下载例如 10 TB,我的服务将崩溃.
    • 如果您要下载 10 个演出,无论它是在指定位置还是在系统使用的 pagefile.sys 中,它最终都会出现在您的磁盘上。话虽如此,响应编写器可以是任何流,如果您愿意,我可以提供一个与您喜欢的任何流不同的示例
    • 我使用此代码using (var stream = new MemoryStream()),但仍将所有数据读取到内存中我使用标题request.AddHeader("Range", "bytes=0-8388607"); 获取部分文件并完美运行。
    • @swestner 这个例子会派上用场,因为我想下载一个简单的 pdf,但我得到的只是响应流中的空值。
    【解决方案2】:

    我在link找到了最佳答案:

     string url = String.Format("https://content.dropboxapi.com/1/files/auto{0}?oauth_consumer_key={1}&oauth_token={2}&oauth_signature={3}%26{4}", path, app-key, access-token, app-secret, access-token-secret);
     HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
     webRequest.Method = "Get";
     WebResponse webResponse = null;
      try
      {
         webResponse = webRequest.GetResponse();
         return webResponse.GetResponseStream();
      }
      catch (Exception ex)
      {
        throw ex;       
      }
    

    【讨论】:

    • 好吧,这个答案使用另一种方法来发出 HTTP 请求 - 而不是问题标题和标签中所述的 RestSharp。这不是问题的直接答案。只是一种解决方法。