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

《打造一个网站或者其他网络应用的文件管理接口(WebApi)第四章“数据库辅助服务器文件访问”》

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

作者:qiujuer

博客:blog.csdn.net/qiujuer

网站:www.qiujuer.net

开源库:Genius-Android

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

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

History

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

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

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

In This

文件可以上传了,下一步就是文件的访问了;只有文件上传没有文件访问。那么数据就是浪费!

目标
  1. 文件访问要能通过上一章文件的那些东西访问磁盘中的文件
  2. 文件要能区分图片文件和其他文件;分别是直接打开和附件保存
  3. 文件要能有浏览器缓存,如打开同一个图片不用重复从服务器加载
分析
  1. 文件的访问这个当然要借助上一章中在数据库中保存的数据进行组合成文件返回流
  2. 直接打开和附件无非就是设置返回头中的Disposition:inline/attachment
  3. 浏览器缓存这个就是设置返回头中的缓存信息了

CodeTime

改动

这次简单,只更改了一个文件;不过更改较大。

流程

简单画了一个;凑合着看啊;就是一个请求来了,先查找数据库,找到该文件的信息;根据这些信息去查找文件。然后返回;没有找到数据 或者没有找到文件都直接返回404。

Get()

        /// <summary>
        /// Get File
        /// </summary>
        /// <param name="name">MD5 Name</param>
        /// <returns>File</returns>
        [HttpGet]
        [Route("{Id}")]
        public async Task<HttpResponseMessage> Get(string Id)
        {
            // Return 304
            // 判断是否含有Tag,有就返回浏览器缓存
            var tag = Request.Headers.IfNoneMatch.FirstOrDefault();
            if (Request.Headers.IfModifiedSince.HasValue && tag != null && tag.Tag.Length > 0)
                return new HttpResponseMessage(HttpStatusCode.NotModified);

            //查找该文件
            Resource model = await db.Resources.FindAsync(Id);

            //未找到文件
            if (model == null)
                return new HttpResponseMessage(HttpStatusCode.BadRequest);

            // 加载文件信息
            FileInfo info = new FileInfo(Path.Combine(ROOT_PATH, model.Folder, model.Id));
            // 文件没有找到
            if (!info.Exists)
                return new HttpResponseMessage(HttpStatusCode.BadRequest);

            FileStream file = null;
            try
            {
                // 打开文件
                file = new FileStream(info.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
                // 新建http响应
                HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                // 设置头部信息
                // GetDisposition() 用于决定文件是直接打开还是提示下载
                // 一般来说图片文件就直接打开,其他文件就提示下载
                ContentDispositionHeaderValue disposition = new ContentDispositionHeaderValue(GetDisposition(model.Type));
                // 设置文件名+扩展
                disposition.FileName = string.Format("{0}.{1}", model.Name, model.Type);
                // 文件名
                disposition.Name = model.Name;
                // 文件大小
                disposition.Size = file.Length;

                if (file.Length < MEMORY_SIZE)
                {
                    // 如果 小于64MB 就直接拷贝到内存流中返回
                    // 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);
                }

                // 设置文件在网络中的ContentType
                // GetContentType() 方法是根据扩展名去查找字典
                // 字典中我收集了大概150种,基本足够使用了
                result.Content.Headers.ContentType = new MediaTypeHeaderValue(GetContentType(model.Type));
                result.Content.Headers.ContentDisposition = disposition;

                // 设置浏览器缓存相关
                // 设置缓存Expires
                result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now).AddHours(1);
                // 缓存最后修改时间
                result.Content.Headers.LastModified = new DateTimeOffset(model.Published);
                // 缓存控制
                result.Headers.CacheControl = new CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromHours(1) };
                // 设置ETag,这里的ETag为了方便就直接使用MD5值
                result.Headers.ETag = new EntityTagHeaderValue(string.Format("\"{0}\"", model.Id));

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

            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }

Get()
方法是这次的精髓部分;其中的作用也都加上了注释了。

ResourceApiController.cs

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Description;
using WebResource.Models;

namespace WebResource.Controllers
{
    [RoutePrefix("Res")]
    public class ResourceApiController : ApiController
    {
        // 操作 数据库
        private WebResourceContext db = new WebResourceContext();
        // 最大内存使用大小
        private static readonly long MEMORY_SIZE = 64 * 1024 * 1024;
        // 文件默认存储位置
        private static readonly string ROOT_PATH = HttpContext.Current.Server.MapPath("~/App_Data/");
        // ContentType字典
        private static Dictionary<string, string> CONTENT_TYPE = null;

        /// <summary>
        /// 初始化字典
        /// </summary>
        static ResourceApiController()
        {
            CONTENT_TYPE = new Dictionary<string, string>();
            CONTENT_TYPE.Add("ex", "application/andrew-inset");
            CONTENT_TYPE.Add("hqx", "application/mac-binhex40");
            CONTENT_TYPE.Add("cpt", "application/mac-compactpro");
            CONTENT_TYPE.Add("doc", "application/msword");
            CONTENT_TYPE.Add("docx", "application/msword");
            CONTENT_TYPE.Add("bin", "application/octet-stream");
            CONTENT_TYPE.Add("dms", "application/octet-stream");
            CONTENT_TYPE.Add("lha", "application/octet-stream");
            CONTENT_TYPE.Add("lzh", "application/octet-stream");
            CONTENT_TYPE.Add("exe", "application/octet-stream");
            CONTENT_TYPE.Add("class", "application/octet-stream");
            CONTENT_TYPE.Add("so", "application/octet-stream");
            CONTENT_TYPE.Add("dll", "application/octet-stream");
            CONTENT_TYPE.Add("oda", "application/oda");
            CONTENT_TYPE.Add("pdf", "application/pdf");
            CONTENT_TYPE.Add("ai", "application/postscript");
            CONTENT_TYPE.Add("eps", "application/postscript");
            CONTENT_TYPE.Add("ps", "application/postscript");
            CONTENT_TYPE.Add("smi", "application/smil");
            CONTENT_TYPE.Add("smil", "application/smil");
            CONTENT_TYPE.Add("mif", "application/vnd.mif");
            CONTENT_TYPE.Add("xls", "application/vnd.ms-excel");
            CONTENT_TYPE.Add("xlsx", "application/vnd.ms-excel");
            CONTENT_TYPE.Add("ppt", "application/vnd.ms-powerpoint");
            CONTENT_TYPE.Add("wbxml", "application/vnd.wap.wbxml");
            CONTENT_TYPE.Add("wmlc", "application/vnd.wap.wmlc");
            CONTENT_TYPE.Add("wmlsc", "application/vnd.wap.wmlscriptc");
            CONTENT_TYPE.Add("bcpio", "application/x-bcpio");
            CONTENT_TYPE.Add("vcd", "application/x-cdlink");
            CONTENT_TYPE.Add("pgn", "application/x-chess-pgn");
            CONTENT_TYPE.Add("cpio", "application/x-cpio");
            CONTENT_TYPE.Add("csh", "application/x-csh");
            CONTENT_TYPE.Add("dcr", "application/x-director");
            CONTENT_TYPE.Add("dir", "application/x-director");
            CONTENT_TYPE.Add("dxr", "application/x-director");
            CONTENT_TYPE.Add("dvi", "application/x-dvi");
            CONTENT_TYPE.Add("spl", "application/x-futuresplash");
            CONTENT_TYPE.Add("gtar", "application/x-gtar");
            CONTENT_TYPE.Add("hdf", "application/x-hdf");
            CONTENT_TYPE.Add("js", "application/x-javascript");
            CONTENT_TYPE.Add("skp", "application/x-koan");
            CONTENT_TYPE.Add("skd", "application/x-koan");
            CONTENT_TYPE.Add("skt", "application/x-koan");
            CONTENT_TYPE.Add("skm", "application/x-koan");
            CONTENT_TYPE.Add("latex", "application/x-latex");
            CONTENT_TYPE.Add("nc", "application/x-netcdf");
            CONTENT_TYPE.Add("cdf", "application/x-netcdf");
            CONTENT_TYPE.Add("sh", "application/x-sh");
            CONTENT_TYPE.Add("shar", "application/x-shar");
            CONTENT_TYPE.Add("swf", "application/x-shockwave-flash");
            CONTENT_TYPE.Add("flv", "application/x-shockwave-flash");
            CONTENT_TYPE.Add("sit", "application/x-stuffit");
            CONTENT_TYPE.Add("sv4cpio", "application/x-sv4cpio");
            CONTENT_TYPE.Add("sv4crc", "application/x-sv4crc");
            CONTENT_TYPE.Add("tar", "application/x-tar");
            CONTENT_TYPE.Add("tcl", "application/x-tcl");
            CONTENT_TYPE.Add("tex", "application/x-tex");
            CONTENT_TYPE.Add("texinfo", "application/x-texinfo");
            CONTENT_TYPE.Add("texi", "application/x-texinfo");
            CONTENT_TYPE.Add("t", "application/x-troff");
            CONTENT_TYPE.Add("tr", "application/x-troff");
            CONTENT_TYPE.Add("roff", "application/x-troff");
            CONTENT_TYPE.Add("man", "application/x-troff-man");
            CONTENT_TYPE.Add("me", "application/x-troff-me");
            CONTENT_TYPE.Add("ms", "application/x-troff-ms");
            CONTENT_TYPE.Add("ustar", "application/x-ustar");
            CONTENT_TYPE.Add("src", "application/x-wais-source");
            CONTENT_TYPE.Add("xhtml", "application/xhtml+xml");
            CONTENT_TYPE.Add("xht", "application/xhtml+xml");
            CONTENT_TYPE.Add("zip", "application/zip");
            CONTENT_TYPE.Add("rar", "application/zip");
            CONTENT_TYPE.Add("gz", "application/x-gzip");
            CONTENT_TYPE.Add("bz2", "application/x-bzip2");
            CONTENT_TYPE.Add("au", "audio/basic");
            CONTENT_TYPE.Add("snd", "audio/basic");
            CONTENT_TYPE.Add("mid", "audio/midi");
            CONTENT_TYPE.Add("midi", "audio/midi");
            CONTENT_TYPE.Add("kar", "audio/midi");
            CONTENT_TYPE.Add("mpga", "audio/mpeg");
            CONTENT_TYPE.Add("mp2", "audio/mpeg");
            CONTENT_TYPE.Add("mp3", "audio/mpeg");
            CONTENT_TYPE.Add("aif", "audio/x-aiff");
            CONTENT_TYPE.Add("aiff", "audio/x-aiff");
            CONTENT_TYPE.Add("aifc", "audio/x-aiff");
            CONTENT_TYPE.Add("m3u", "audio/x-mpegurl");
            CONTENT_TYPE.Add("rmm", "audio/x-pn-realaudio");
            CONTENT_TYPE.Add("rmvb", "audio/x-pn-realaudio");
            CONTENT_TYPE.Add("ram", "audio/x-pn-realaudio");
            CONTENT_TYPE.Add("rm", "audio/x-pn-realaudio");
            CONTENT_TYPE.Add("rpm", "audio/x-pn-realaudio-plugin");
            CONTENT_TYPE.Add("ra", "audio/x-realaudio");
            CONTENT_TYPE.Add("wav", "audio/x-wav");
            CONTENT_TYPE.Add("wma", "audio/x-wma");
            CONTENT_TYPE.Add("pdb", "chemical/x-pdb");
            CONTENT_TYPE.Add("xyz", "chemical/x-xyz");
            CONTENT_TYPE.Add("bmp", "image/bmp");
            CONTENT_TYPE.Add("gif", "image/gif");
            CONTENT_TYPE.Add("ief", "image/ief");
            CONTENT_TYPE.Add("jpeg", "image/jpeg");
            CONTENT_TYPE.Add("jpg", "image/jpeg");
            CONTENT_TYPE.Add("jpe", "image/jpeg");
            CONTENT_TYPE.Add("png", "image/png");
            CONTENT_TYPE.Add("tiff", "image/tiff");
            CONTENT_TYPE.Add("tif", "image/tiff");
            CONTENT_TYPE.Add("djvu", "image/vnd.djvu");
            CONTENT_TYPE.Add("djv", "image/vnd.djvu");
            CONTENT_TYPE.Add("wbmp", "image/vnd.wap.wbmp");
            CONTENT_TYPE.Add("ras", "image/x-cmu-raster");
            CONTENT_TYPE.Add("pnm", "image/x-portable-anymap");
            CONTENT_TYPE.Add("pbm", "image/x-portable-bitmap");
            CONTENT_TYPE.Add("pgm", "image/x-portable-graymap");
            CONTENT_TYPE.Add("ppm", "image/x-portable-pixmap");
            CONTENT_TYPE.Add("rgb", "image/x-rgb");
            CONTENT_TYPE.Add("xbm", "image/x-xbitmap");
            CONTENT_TYPE.Add("xpm", "image/x-xpixmap");
            CONTENT_TYPE.Add("xwd", "image/x-xwindowdump");
            CONTENT_TYPE.Add("igs", "model/iges");
            CONTENT_TYPE.Add("iges", "model/iges");
            CONTENT_TYPE.Add("msh", "model/mesh");
            CONTENT_TYPE.Add("mesh", "model/mesh");
            CONTENT_TYPE.Add("silo", "model/mesh");
            CONTENT_TYPE.Add("wrl", "model/vrml");
            CONTENT_TYPE.Add("vrml", "model/vrml");
            CONTENT_TYPE.Add("css", "text/css");
            CONTENT_TYPE.Add("html", "text/html");
            CONTENT_TYPE.Add("htm", "text/html");
            CONTENT_TYPE.Add("asc", "text/plain");
            CONTENT_TYPE.Add("txt", "text/plain");
            CONTENT_TYPE.Add("rtx", "text/richtext");
            CONTENT_TYPE.Add("rtf", "text/rtf");
            CONTENT_TYPE.Add("sgml", "text/sgml");
            CONTENT_TYPE.Add("sgm", "text/sgml");
            CONTENT_TYPE.Add("tsv", "text/tab-separated-values");
            CONTENT_TYPE.Add("wml", "text/vnd.wap.wml");
            CONTENT_TYPE.Add("wmls", "text/vnd.wap.wmlscript");
            CONTENT_TYPE.Add("etx", "text/x-setext");
            CONTENT_TYPE.Add("xsl", "text/xml");
            CONTENT_TYPE.Add("xml", "text/xml");
            CONTENT_TYPE.Add("mpeg", "video/mpeg");
            CONTENT_TYPE.Add("mpg", "video/mpeg");
            CONTENT_TYPE.Add("mpe", "video/mpeg");
            CONTENT_TYPE.Add("qt", "video/quicktime");
            CONTENT_TYPE.Add("mov", "video/quicktime");
            CONTENT_TYPE.Add("mxu", "video/vnd.mpegurl");
            CONTENT_TYPE.Add("avi", "video/x-msvideo");
            CONTENT_TYPE.Add("movie", "video/x-sgi-movie");
            CONTENT_TYPE.Add("wmv", "video/x-ms-wmv");
            CONTENT_TYPE.Add("asf", "video/x-ms-asf");
            CONTENT_TYPE.Add("ice", "x-conference/x-cooltalk");
        }

        /// <summary>
        /// Get ContentType
        /// </summary>
        /// <param name="type">Type</param>
        /// <returns>ContentType</returns>
        private static string GetContentType(string type)
        {
            // 获取文件对应的ContentType
            try
            {
                string contentType = CONTENT_TYPE[type];
                if (contentType != null)
                    return contentType;
            }
            catch { }
            return "application/octet-stream" + type;
        }

        /// <summary>
        /// Get ContentDisposition
        /// </summary>
        /// <param name="type">Type</param>
        /// <returns>ContentDisposition</returns>
        private static string GetDisposition(string type)
        {
            // 判断使用浏览器打开还是附件模式
            if (GetContentType(type).StartsWith("image"))
            {
                return "inline";
            }
            return "attachment";
        }

        /// <summary>
        /// Get File
        /// </summary>
        /// <param name="name">MD5 Name</param>
        /// <returns>File</returns>
        [HttpGet]
        [Route("{Id}")]
        public async Task<HttpResponseMessage> Get(string Id)
        {
            // Return 304
            // 判断是否含有Tag,有就返回浏览器缓存
            var tag = Request.Headers.IfNoneMatch.FirstOrDefault();
            if (Request.Headers.IfModifiedSince.HasValue && tag != null && tag.Tag.Length > 0)
                return new HttpResponseMessage(HttpStatusCode.NotModified);

            //查找该文件
            Resource model = await db.Resources.FindAsync(Id);

            //未找到文件
            if (model == null)
                return new HttpResponseMessage(HttpStatusCode.BadRequest);

            // 加载文件信息
            FileInfo info = new FileInfo(Path.Combine(ROOT_PATH, model.Folder, model.Id));
            // 文件没有找到
            if (!info.Exists)
                return new HttpResponseMessage(HttpStatusCode.BadRequest);

            FileStream file = null;
            try
            {
                // 打开文件
                file = new FileStream(info.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
                // 新建http响应
                HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
                // 设置头部信息
                // GetDisposition() 用于决定文件是直接打开还是提示下载
                // 一般来说图片文件就直接打开,其他文件就提示下载
                ContentDispositionHeaderValue disposition = new ContentDispositionHeaderValue(GetDisposition(model.Type));
                // 设置文件名+扩展
                disposition.FileName = string.Format("{0}.{1}", model.Name, model.Type);
                // 文件名
                disposition.Name = model.Name;
                // 文件大小
                disposition.Size = file.Length;

                if (file.Length < MEMORY_SIZE)
                {
                    // 如果 小于64MB 就直接拷贝到内存流中返回
                    // 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);
                }

                // 设置文件在网络中的ContentType
                // GetContentType() 方法是根据扩展名去查找字典
                // 字典中我收集了大概150种,基本足够使用了
                result.Content.Headers.ContentType = new MediaTypeHeaderValue(GetContentType(model.Type));
                result.Content.Headers.ContentDisposition = disposition;

                // 设置浏览器缓存相关
                // 设置缓存Expires
                result.Content.Headers.Expires = new DateTimeOffset(DateTime.Now).AddHours(1);
                // 缓存最后修改时间
                result.Content.Headers.LastModified = new DateTimeOffset(model.Published);
                // 缓存控制
                result.Headers.CacheControl = new CacheControlHeaderValue() { Public = true, MaxAge = TimeSpan.FromHours(1) };
                // 设置ETag,这里的ETag为了方便就直接使用MD5值
                result.Headers.ETag = new EntityTagHeaderValue(string.Format("\"{0}\"", model.Id));

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

            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }

        /// <summary>
        /// Post File
        /// </summary>
        /// <param name="Id">Md5</param>
        /// <returns>Resource</returns>
        [HttpPost]
        [Route("Upload/{Id?}")]
        [ResponseType(typeof(Resource))]
        public async Task<IHttpActionResult> Post(string Id = null)
        {
            List<Resource> resources = new List<Resource>();

            // multipart/form-data
            var provider = new MultipartMemoryStreamProvider();
            await Request.Content.ReadAsMultipartAsync(provider);

            foreach (var item in provider.Contents)
            {
                if (item.Headers.ContentDisposition.FileName != null)
                {
                    //Strem
                    var ms = item.ReadAsStreamAsync().Result;

                    using (var br = new BinaryReader(ms))
                    {
                        if (ms.Length <= 0)
                            break;
                        var data = br.ReadBytes((int)ms.Length);
                        //Md5
                        string id = HashUtils.GetMD5Hash(data);

                        Resource temp = await db.Resources.FindAsync(id);
                        if (temp == null)
                        {
                            //Create
                            Resource resource = new Resource();
                            resource.Id = id;
                            resource.Size = ms.Length;
                            resource.Cursor = resource.Size;
                            resource.Published = DateTime.Now;
                            //Info
                            FileInfo info = new FileInfo(item.Headers.ContentDisposition.FileName.Replace("\"", ""));
                            resource.Type = info.Extension.Substring(1).ToLower();
                            resource.Name = info.Name.Substring(0, info.Name.LastIndexOf("."));
                            //Relative
                            resource.Folder = DateTime.Now.ToString("yyyyMM/dd/", DateTimeFormatInfo.InvariantInfo);

                            //Write
                            try
                            {
                                string dirPath = Path.Combine(ROOT_PATH, resource.Folder);
                                if (!Directory.Exists(dirPath))
                                {
                                    Directory.CreateDirectory(dirPath);
                                }

                                File.WriteAllBytes(Path.Combine(dirPath, resource.Id), data);
                                //Save To Datebase
                                db.Resources.Add(resource);
                                await db.SaveChangesAsync();
                                temp = await db.Resources.FindAsync(resource.Id);
                            }
                            catch { }
                        }
                        if (temp != null)
                            resources.Add(temp);
                    }
                }
            }

            if (resources.Count == 0)
                return BadRequest();
            else if (resources.Count == 1)
                return Ok(resources.FirstOrDefault());
            else
                return Ok(resources);
        }
    }
}

这个是修改后的API文件,Post相对上一章没有进行修改;添加了Get,和其他几个方法以及变量。

RunTime

Api

运行之后首先来看看现在的API,一个是上传,一个是访问;简单吧?

Home/Upload

上传两个,一个图片一个Zip

可以看见返回了两个文件的信息,分别记住两个文件的ID,来访问一下试试。

Image

可以看见图片是直接打开在浏览器中的;下面来看看Zip的文件咋样。

可以看见是以下载文件的方式返回的。

请求返回
Zip

通过浏览器调试,我们可以看见Zip文件的返回信息与上面Get方法中设置的参数是一样的;代表了方法正确执行。

Image

可以看见图片的是以 Inline 的形式打开的;所以是在浏览器中直接显示。

再次请求图片:

通过再次请求图片;可以看见服务器返回的是304.意思就是浏览器自己使用自己的缓存信息;无需重复从服务器加载。这个无疑试用与图片的情况。

所有的工作都是按照我们预想的进行;能得到这样的结果是不错的。

以后你的网站中就能使用:.../Res/.....
简单的一个地址就OK了;无论是图片;附件;css;js;等等都是可行的。而且也没有暴露你的文件存储信息,

你敢说不爽?反正我是觉得挺爽的!

END

有到了结束的时候了。

资源

WebResource-004_20141205

下一章

针对于下一章,有两个方向:

  • 一个是开发一个管理界面
  • 还有就是开发针对图片的Get方法(这个方法能实现图片的压缩,分割等功能)

但是没有想好,大伙想看关于那个的?

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

作者:qiujuer

博客:blog.csdn.net/qiujuer

网站:www.qiujuer.net

开源库:Genius-Android

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

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

时间: 2024-10-28 15:23:04

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

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

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

[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/4172

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

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

windows 7 资源管理器预览 js 文件方法

1. 打开注册表: 开始 -> 运行 -> regedit 2. 导航至HKEY_CLASSES_ROOT, 新建.js注册项(如果还没有的话) 3. 查看右侧(默认)的键值, 将其设置为JSFile, 如果存在PerceivedType键,请将其值修改为 text 4. 导航至HKEY_CLASSES_ROOT -> JSFile, 创建shellex注册项, 然后在shellex下再创建 {8895b1c6-b41f-4c1c-a562-0d564250836f} 注册项(这是一个固

Windows 10 删除资源管理器中7个文件夹

Windows 10 安装完成之后 ,在资源管理器中会存在 7 个文件夹,他们分别是:图片.视频.下载.音乐.桌面.文档.3D对象. 我们可以通过修改注册表的方式,隐藏这7个文件夹.相关注册表内容如下: Windows Registry Editor Version 5.00 ; 修改 ThisPCPolicy 属性可以决定相关文件夹展示或者隐藏.如果想展示修改值为 Show ,如果想隐藏修改值为 Hide ; HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft 这个路径

SQL server2008-对象资源管理器-数据库

数据库:系统数据库(master.model.msdb.tempdb).数据库快照.自定义数据库组成 三部分组成. master:Master数据库是SQL Server中最重要的系统数据库,记录了SQL Server系统级的信息.包括:系统中所有的登录账号及其密码,系统配置信息,所有数据库的信息,所有用户数据库的主文件地址等,还包括许多系统存储过程,用以执行某些系统操作.Master数据库是整个系统中最重要的数据库,如果丢失Master数据库,对于恢复所有用户数据库将非常困难.因此,保存Mas

yarn资源管理器高可用性的实现

资源管理器高可用性 . The ResourceManager (RM) is responsible for tracking the resources in a cluster, and scheduling applications (e.g., MapReduce jobs). Prior to Hadoop 2.4, the ResourceManager is the single point of failure in a YARN cluster. The High Avail

[转]C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件

原文:http://www.crifan.com/csharp_call_explorer_to_open_destinate_folder_and_select_specific_file/ C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件 折腾: C#中如何在右下角添加提示窗口,用于显示打开文件和文件夹 的过程中,需要实现,点击对应LinkLabel后,调用资源管理器,打开对应的文件夹. [