Dropbox .NET Downloading large files using GetContentAsStreamAsync

做~自己de王妃 提交于 2019-12-14 01:51:39

问题


I want to use the Dropbox Api for .NET to allow my users to download files I have stored in Dropbox from my site. In other words I want to keep the big files in Dropbox and use Dropbox as storage. The size of the files ranges from small (a few MB) to Big (a couple of Hundred MB) This is the code I have:

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

This Code is based in the Code Dropbox has in their documentation for tracking the progress of a download. When the files are small I can download them fine. I could even use the simpler code to download in one pass instead of downloading as chunks of 4MB. But when the file is bigger I can download more using the chunks of data. But for the bigger files (bigger than 20MB) I still run into this error that says the Request was aborted. Here's the 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: 

Thanks in advance


回答1:


The problem was in deed a timeout that I had to set in the Dropbox Client, as Greg pointed out in the Dropbox Forum. I am putting here the final code may be it will help somebody in the future...

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

Note that I had to add a reference to System.Net.Http.WebRequest



来源:https://stackoverflow.com/questions/43208069/dropbox-net-downloading-large-files-using-getcontentasstreamasync

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!