Dropbox .NET使用GetContentAsStreamAsync下载大文件

时间:2017-04-04 13:03:34

标签: c# .net dropbox-api

我想使用Dropbox Api for .NET允许我的用户从我的网站下载我存储在Dropbox中的文件。换句话说,我想保留大文件 Dropbox并使用Dropbox作为存储。 文件的大小范围从小(几MB)到大(几百MB) 这是我的代码:

public async void DownloadChunks(string argFilePath)
{
    var aFileName = Path.GetFileName(argFilePath);

    using (var aDropboxClient = new DropboxClient(anAccessToken))
    {
        var aResponse = await aDropboxClient.Files.DownloadAsync(argFilePath);

        ulong aFileSize = aResponse.Response.Size;
        const int aBufferSize = 4 * 1024 * 1024;

        var aBuffer = new byte[aBufferSize];

        using (var aDropboxContentStream = await aResponse.GetContentAsStreamAsync())
        {
            Response.BufferOutput = false;
            Response.AddHeader("content-disposition", "attachment;filename=" + aFileName);
            Response.AddHeader("Content-Length", aFileSize.ToString());
            int aLengthOfBytesRead = aDropboxContentStream.Read(aBuffer, 0, aBufferSize);
            while (aLengthOfBytesRead > 0)
            {
                Response.OutputStream.Write(aBuffer, 0, aLengthOfBytesRead);
                aLengthOfBytesRead = aDropboxContentStream.Read(aBuffer, 0, aBufferSize);
            }
        }
    }
}

此代码基于代码Dropbox在其文档中用于跟踪下载进度。 当文件很小时我可以下载它们。我甚至可以使用更简单的代码一次下载而不是下载为4MB的块。但是当文件更大时,我可以使用数据块下载更多。 但对于较大的文件(大于20MB),我仍然遇到这个错误,说请求被中止。 这是StackTrace:

System.IO.IOException was unhandled by user code
HResult=-2146232800
Message=The read operation failed, see inner exception.
Source=System.Net.Http
StackTrace:
   at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at System.Net.Http.DelegatingStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at test_DropboxTest.<DownloadWithTracking>d__0.MoveNext() in d:\Dropbox\NPC Website\website\test\DropboxTest.aspx.cs:line 41
InnerException: System.Net.WebException
   HResult=-2146233079
   Message=The request was aborted: The request was canceled.
   Source=System
   StackTrace:
        at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size)
        at System.Net.Http.HttpClientHandler.WebExceptionWrapperStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   InnerException: 

提前致谢

1 个答案:

答案 0 :(得分:0)

正如Greg在Dropbox论坛中指出的那样,问题在于我必须在Dropbox客户端中设置超时。 我在这里放最后的代码可能会帮助将来的某个人......

public async void DownloadWithTracking(string argFilePath)
    {
        var aFileName = Path.GetFileName(argFilePath);
        string anAccessToken = "";

        var aHttpClient = new HttpClient(new WebRequestHandler { ReadWriteTimeout = 10 * 1000 }) { Timeout = TimeSpan.FromMinutes(20) };
        var aDorpboxConfig = new DropboxClientConfig("DownloadApp") { HttpClient = aHttpClient };

        using (var aDropboxClient = new DropboxClient(anAccessToken, aDorpboxConfig))
        {
            var aResponse = await aDropboxClient.Files.DownloadAsync(argFilePath);

            ulong aFileSize = aResponse.Response.Size;
            const int aBufferSize = 4 * 1024 * 1024;

            var aBuffer = new byte[aBufferSize];

            using (var aDropboxContentStream = await aResponse.GetContentAsStreamAsync())
            {
                Response.BufferOutput = false;
                Response.AddHeader("content-disposition", "attachment;filename=" + aFileName);
                Response.AddHeader("Content-Length", aFileSize.ToString());
                int aLengthOfBytesRead = aDropboxContentStream.Read(aBuffer, 0, aBufferSize);
                while (aLengthOfBytesRead > 0)
                {
                    Response.OutputStream.Write(aBuffer, 0, aLengthOfBytesRead);
                    aLengthOfBytesRead = aDropboxContentStream.Read(aBuffer, 0, aBufferSize);
                }
            }
        }
    }

请注意,我必须添加对System.Net.Http.WebRequest

的引用