[WebApi] 捣鼓一个资源管理器--文件下载

《打造一个网站或者其他网络应用的文件管理接口(WebApi)第一章--之-- “文件下载” 》

========================================================

作者:qiujuer

博客:blog.csdn.net/qiujuer

网站:www.qiujuer.net

开源库:Genius-Android

转载请注明出处:blog.csdn.net/qiujuer/article/details/41621781

========================================================

In This

访问一个网上的图片资源,我想你应该遇到过这样的情况:

常规情况下:http://www.qiujuer.net/Statics/Image/Home/HeadPortrait.png

当然还有这样:http://www.qiujuer.net/Resource/75CDF243C30750D397A90E58D412B22E

可以看到得到同样的一张图片却能采用不一样的地址,特别是在第二个地址中却没有文件的后缀。

这个奇葩了吧?有感觉到很奇怪的么?

其实很简单

第一种情况中是访问的当前图片存储在网站服务器中的地址。

换言之其在”cdn.duitang.com“网站的服务器中存储的地址应该是文件夹"uploads/item/201403/04”下的“20140304122431_XMCuj.jpeg”文件。

而输入第一张图片中的地址的时候,web服务器将会在其指定文件夹下去搜寻该文件,然后返回图片。

第二种情况中你能说是在”www.qiujuer.net“网站的“Resource”文件夹下的”75CDF243C30750D397A90E58D412B22E“文件么?

有这样的可能,但是在这个情况下不是!

其工作原理是访问当前URL的时候触发的是“Resource”接口,然后传入了ID=”75CDF243C30750D397A90E58D412B22E“。

然后WebApi服务器根据该ID通过一定的方式去寻找图片资源,然后通过资源的方式返回图片;

而其图片究竟是存在哪里你并不知道,有可能是在当前网站目录下的某个文件夹,也可能是其他盘;总之是不固定的。

请问针对第二种情况你能使用爬虫软件去爬该图片么?如果可以;但是我给这个接口加上指定的用户权限呢?

说了这么多,我们来实现一下!

CodeTime

首先打开VS-新建项目-web应用程序-名称“WebResource”-WebApi

进入项目-删除ValuesController

添加一个webapi控制器-ResourceApiController

在其中实现Get方法:

    [RoutePrefix("Resource")]
    public class ResourceApiController : ApiController
    {
        private static readonly long MEMORY_SIZE = 64 * 1024 * 1024;
        private static readonly string ROOT_PATH = HttpContext.Current.Server.MapPath("~/App_Data/");

        [HttpGet]
        [Route("{Id}")]
        public async Task<HttpResponseMessage> Get(string Id)
        {
            // 进入时判断当前请求中是否含有 ETag 标识,如果有就返回使用浏览器缓存
            // Return 304
            var tag = Request.Headers.IfNoneMatch.FirstOrDefault();
            if (Request.Headers.IfModifiedSince.HasValue && tag != null && tag.Tag.Length > 0)
                return new HttpResponseMessage(HttpStatusCode.NotModified);

            // 进行模拟 App_Data/Image/{id}.png
            // 打开找到文件
            FileInfo info = new FileInfo(Path.Combine(ROOT_PATH, "Image", Id + ".png"));
            if (!info.Exists)
                return new HttpResponseMessage(HttpStatusCode.BadRequest);

            FileStream file = null;
            try
            {
                // 打开文件
                file = new FileStream(info.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
                HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                // 在浏览器中显示 inline
                ContentDispositionHeaderValue disposition = new ContentDispositionHeaderValue("inline");
                // 写入文件基本信息
                disposition.FileName = file.Name;
                disposition.Name = file.Name;
                disposition.Size = file.Length;

                // 判断是否大于64Md,如果大于就采用分段流返回,否则直接返回
                if (file.Length < MEMORY_SIZE)
                {
                    //Copy To Memory And Close.
                    byte[] bytes = new byte[file.Length];
                    await file.ReadAsync(bytes, 0, (int)file.Length);
                    file.Close();
                    MemoryStream ms = new MemoryStream(bytes);

                    result.Content = new ByteArrayContent(ms.ToArray());
                }
                else
                {
                    result.Content = new StreamContent(file);
                }

                // 写入文件类型,这里是图片png
                result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
                result.Content.Headers.ContentDisposition = disposition;
                // 设置缓存信息,该部分可以没有,该部分主要是用于与开始部分结合以便浏览器使用304缓存
                // Set Cache
                result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now).AddHours(1);
                // 这里应该写入文件的存储日期
                result.Content.Headers.LastModified = new DateTimeOffset(DateTime.Now);
                result.Headers.CacheControl = new CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromHours(1) };
                // 设置Etag,这里就简单采用 Id
                result.Headers.ETag = new EntityTagHeaderValue(string.Format("\"{0}\"", Id));

                // 返回请求
                return result;
            }
            catch
            {
                if (file != null)
                {
                    file.Close();
                }
            }

            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
    }

基本上都进行了注释,如果有不了解的还请评论中写下。

RunTime

准备工作

在运行前我们需要在“App_Data”下建立文件夹“Image”。然后拷贝两张图片“001.png”\"002.png"进去。

运行

点击运行-浏览器中输入URL:http://localhost:60586/Resource/001

把ID换成002再次输入:http://localhost:60586/Resource/002

OK,基本的功能我们实现了。

END Time

为什么是“App_Data”文件夹?

在这里有必要说的是“App_Data”在.NET Web 中是受保护的对象。无法直接通过URL访问;不信?

来试试,输入URL:http://localhost:60586/App_Data/Image/002.png

所以说,一般数据库文件是可以放在该文件夹下的;当然现在你可以把图片放在下面,然后通过接口访问。

是否太简单了?

的确,在这里第一章只是一个开始;后面会逐渐的进行扩大化。

比如增加:上传、其他非图片文件、以及不是001,002等名称,而是运算一个Id出来、当然还有加上数据的管理等等。

代码

这次的代码打包了;但是CSDN死活传不上去,我去啊!不过好在也简单;就一个方法;下一章中一起打包吧。

时间: 2024-08-05 19:03:42

[WebApi] 捣鼓一个资源管理器--文件下载的相关文章

[WebApi] 捣鼓一个资源管理器--多文件上传

<打造一个网站或者其他网络应用的文件管理接口(WebApi)第二章"多文件上传"> ======================================================== 作者:qiujuer 博客:blog.csdn.net/qiujuer 网站:www.qiujuer.net 开源库:Genius-Android 转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41675299 ====

[WebApi] 捣鼓一个资源管理器--数据库辅助服务器文件访问

<打造一个网站或者其他网络应用的文件管理接口(WebApi)第四章"数据库辅助服务器文件访问"> ======================================================== 作者:qiujuer 博客:blog.csdn.net/qiujuer 网站:www.qiujuer.net 开源库:Genius-Android 转载请注明出处: http://blog.csdn.net/qiujuer/article/details/41721

[WebApi] 捣鼓一个资源管理器--多文件上传+数据库辅助

<打造一个网站或者其他网络应用的文件管理接口(WebApi)第三章"多文件上传+数据库辅助存储"> ======================================================== 作者:qiujuer 博客:blog.csdn.net/qiujuer 网站:www.qiujuer.net 开源库:Genius-Android 转载请注明出处: http://blog.csdn.net/qiujuer/article/details/4172

[WebApi] 捣鼓一个资源管理器--服务器端分割压缩图片

<打造一个网站或者其他网络应用的文件管理接口(WebApi)第五章"服务器端分割压缩图片"> ======================================================== 作者:qiujuer 博客:blog.csdn.net/qiujuer 网站:www.qiujuer.net 开源库:Genius-Android 转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41826865

更改win7资源管理器启动位置

打开资源管理器属性,在目标(T)后边加上: /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D} 俺滴笨笨原本目标(T)是: %windir%\explorer.exe  -----默认打开的是“库” 添加后: %windir%\explorer.exe /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}  ----打开的是“计算机” /N,::{450D8FBA-AD25-11D0-98A8-0800361B1103}  

Cocos2d-x 3.2 Lua示例 AssetsManagerTest(资源管理器)

Cocos2d-x 3.2 Lua示例 AssetsManagerTest(资源管理器) 本篇博客介绍Cocos2d-x 为我们提供的一个类--AssetsManager在Lua中的使用例子,效果如下图: Cocos2d-x 给出的例子是AssetsManagerTest,进入会发现三个菜单项: enter reset update enter是进入场景,reset是删除本地版本,重新设置,update就是更新资源文件. 笔者使用LDT打开lua-tests测试项目: 在src目录下找到Asse

windows资源管理器(只能看,不能用)

实现Windows资源管理器 问题描述 Windows资源管理器是用来管理计算机资源的窗口,电脑里所有的文件都可以在资源管理器里找到,可以在资源管理器里查看文件夹的分层结构,可以利用资源管理器快速进行文件和文件夹的操作.例如,磁盘(根).目录.不同类型的文件. 其中,文件信息包括文件名.类型.创建时间.文件大小等:磁盘信息包括磁盘名称.总大小.可用空间等:目录信息包括目录名称.修改日期.大小.对象数等. 基本要求 (1)构造一个空的资源管理器: (2)新建/删除磁盘: (3)在当前选择目录下新建

使用Windows Form 制作一个简易资源管理器

自制一个简易资源管理器----TreeView控件 第一步.新建project,进行基本设置:(Set as StartUp Project:View/Toolbox/TreeView) 第二步.开始添加节点 添加命名空间using System.IO; 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Dra

自己动手做一个小型“资源管理器”吧

自己动手做一个小型“资源管理器”吧 注:tvDirectory是treeView控件,lvDirectory是listView控件 首先搭建一下界面: 左边是treeView控件,右边是listView控件.(listView的网格线只需把GridLins设置成True就可以了.) 由于要用到IO流,所以别忘了导入命名空间:using System.IO; 我们只要创建一个文件类就可以了: 1 public class MyFile 2 { 3 //文件长度 4 public float Fil