Dropbox .NET使用GetContentAsStreamAsync下载大文件 [英] Dropbox .NET Downloading large files using GetContentAsStreamAsync

查看:59
本文介绍了Dropbox .NET使用GetContentAsStreamAsync下载大文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

此代码基于Code Dropbox在其文档中提供的用于跟踪下载进度的代码。
当文件较小时,我可以很好地下载它们。我什至可以使用更简单的代码来一次下载,而不必下载4MB的块。但是,当文件较大时,我可以使用数据块下载更多文件。
但是对于较大的文件(大于20MB),我仍然遇到此错误,该错误表明请求已中止。
这是StackTrace:

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: 

预先感谢

推荐答案

问题的确是我必须在Dropbox Client中设置超时,正如Greg指出的那样。 Dropbox论坛。
我将最终代码放在这里,可能会在将来对某人有所帮助...

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

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

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

这篇关于Dropbox .NET使用GetContentAsStreamAsync下载大文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆