.Net WebAPI 高速下载文件接口实现
2017-09-30 14:03
441 查看
接触WebAPI一年多了,感觉是个承上启下,开创未来的技术。老一辈程序员写接口就像写方法一样,不需要了解太多网页的知识,却可以在浏览器中访问这些接口;由于是基于HTTP协议,因此不管是PC、手机还是嵌入式均可顺利访问。对于当下软件多终端的设计结构来说,这就像是量身订做的一样。
在开发的过程中遇到了一些问题,大部分都可通过百度找到解决方案,但是有一个问题却一直没有很好地解决,那就是文件下载速度的问题。
网上找到的WebAPI下载文件的代码大都是以下方式:
这种方式虽然可以实现文件下载,但是下载速度实在太慢(在局域网中下载速度只有50K),稍大一点的文件就有可能导致客户端请求超时。
改为以下方式可实现高速下载的目的。在百兆局域网内实际测试可满速下载。
在开发的过程中遇到了一些问题,大部分都可通过百度找到解决方案,但是有一个问题却一直没有很好地解决,那就是文件下载速度的问题。
网上找到的WebAPI下载文件的代码大都是以下方式:
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Runtime.Remoting.Contexts; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Http; using System.Web.Http.Cors; using System.Net.Http.Headers; namespace Service.Controller { public partial class APIController : ApiController { public HttpResponseMessage GetFileResponse(string FilePath, string FileName = null, string ContentType = "application/octet-stream") { FileStream fs; HttpResponseMessage result; fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read); result = new HttpResponseMessage(System.Net.HttpStatusCode.OK) { Content = new StreamContent(fs) }; result.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); result.Content.Headers.ContentDisposition.FileName = (null != FileName ? FileName : Path.GetFileName(FilePath)); return result; } } }
这种方式虽然可以实现文件下载,但是下载速度实在太慢(在局域网中下载速度只有50K),稍大一点的文件就有可能导致客户端请求超时。
改为以下方式可实现高速下载的目的。在百兆局域网内实际测试可满速下载。
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Runtime.Remoting.Contexts; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Http; using System.Web.Http.Cors; using System.Net.Http.Headers; namespace Service.Controller { public partial class APIController : ApiController { #region 辅助函数 public interface IWriteStreamToResponse<T> { T Suorce { get; set; } void WriteToStream(Stream outputStream, HttpContent content, TransportContext context); } public class StreamFromFileName : IWriteStreamToResponse<string> { private string _suorce; public string Suorce { get { return _suorce; } set { _suorce = value; } } public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context) { try { var buffer = new byte[1024 * 1024 * 2]; using (var video = File.Open(_suorce, FileMode.Open, FileAccess.Read, FileShare.Read)) { var length = (int)video.Length; var bytesRead = 1; while (length > 0 && bytesRead > 0) { bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length)); await outputStream.WriteAsync(buffer, 0, bytesRead); length -= bytesRead; } } } catch (Exception ex) { return; } finally { outputStream.Close(); } } } public class StreamFromBytes : IWriteStreamToResponse<Stream> { private Stream _source; public Stream Suorce { get { return _source; } set { _source = value; } } public async void WriteToStream(Stream outputStream, HttpContent content, TransportContext context) { try { var buffer = new byte[1024 * 1024 * 2]; using (var video = _source) { var length = (int)video.Length; var bytesRead = 1; while (length > 0 && bytesRead > 0) { bytesRead = video.Read(buffer, 0, Math.Min(length, buffer.Length)); await outputStream.WriteAsync(buffer, 0, bytesRead); length -= bytesRead; } } } catch (Exception ex) { return; } finally { _source.Close(); outputStream.Close(); } } } #endregion public HttpResponseMessage GetFileResponse(string FilePath, string FileName = null, string ContentType = "application/octet-stream") { HttpResponseMessage response; IWriteStreamToResponse<string> ResponseStreamWriter; Action<Stream, HttpContent, TransportContext> sendMethod; ResponseStreamWriter = new StreamFromFileName() { Suorce = FilePath }; sendMethod = ResponseStreamWriter.WriteToStream; response = Request.CreateResponse(); response.Content = new System.Net.Http.PushStreamContent(sendMethod); response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); response.Content.Headers.ContentDisposition.FileName = (null != FileName ? FileName : Path.GetFileName(FilePath)); return response; } } }
相关文章推荐
- .Net WebAPI 高速下载文件接口实现
- ASP.NET WebApi服务接口如何防止重复请求实现HTTP幂等性(八)
- .NET WebApi上传文件接口(带其他参数)
- 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传
- windows wininet api 实现下载web服务器文件(l历史代码,贴出共享)
- asp.net 模拟CURL调用微信公共平台API 上传下载多媒体文件接口
- ASP.NET Web大文件下载的实现思路及代码
- 一个简单的QQ隐藏图生成算法 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传
- AWS S3 API实现文件上传下载(ASP.NET MVC)
- 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现!
- 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现! 转
- Asp.net 2.0 用 FileUpload 控件实现多文件上传 用户控件(示例代码下载)
- ASP.NET实现文件的上传与下载(包括用数据库存取文件)
- asp.net中下载文件的实现方法
- Asp.net 2.0 用 FileUpload 控件实现多文件上传 用户控件(示例代码下载).NET技术
- ASP.NET 2.0 HttpHandler实现对某种文件类型权限保护(示例代码下载)
- 将更智能的 ASP.NET 文件下载体验内置到您的 Web 应用程序中(zz)
- asp.net下载文件实现代码
- 实现用C#和VB.NET调用Ghostscript的API,把Postscript文件转为PDF文件。
- Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (转,尚未整理)