为了说明自定义虚拟路径,这里弄个示例,仅仅用一个压缩包存放一个网站的多个文件。

  这个东西是要需要通过实现3个抽象类来实现:

  • System.Web.Hosting.VirtualPathProvider;
  • System.Web.Hosting.VirtualDirectory;
  • System.Web.Hosting.VirtualFile;

  因为,我真的不知道如何去缩减,代码比较多。首先新建一个Web项目,然后添加如下3个类:

  1、虚拟目录提供者类:

 
    public class ZipVirtualPathProvider : System.Web.Hosting.VirtualPathProvider
{
private string fileRootPath;
private string virtualRootPath;
private ZipVirtualDirectory root; public ZipVirtualPathProvider()
{
this.fileRootPath = HttpRuntime.AppDomainAppPath;
this.virtualRootPath = HttpRuntime.AppDomainAppVirtualPath + "/";
string path = string.Format("{0}App_Data\\test.zip", fileRootPath);
using (ZipFile zipFile = new ZipFile(path))
{
// 创建根目录
this.root = new ZipVirtualDirectory(virtualRootPath);
foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry entry in zipFile)
{
string name = string.Format("{0}{1}", this.virtualRootPath, entry.Name);
VirtualDirectory parent = GetParentDirectory(name);
ZipVirtualDirectory zipParent = parent as ZipVirtualDirectory;
System.Web.Hosting.VirtualFileBase vfb;
if (entry.IsDirectory)
{
vfb = new ZipVirtualDirectory(name);
}
else
{
System.IO.Stream stream = zipFile.GetInputStream(entry);
int size = (int)entry.Size;
byte[] buffer = ReadAllBytes(stream, size);
vfb = new ZipVirtualFile(name, buffer);
}
zipParent.AddVirtualItem(vfb);
}
}
} //寻找子目录所属的父目录
private VirtualDirectory GetParentDirectory(string virtualPath)
{
// 从根目录开始找,直到找不到为止,说明就是所属的父目录,加入父目录中
VirtualDirectory root = this.root;
while (true)
{
bool isContinue = false;
foreach (VirtualDirectory dir in root.Directories)
{
if (virtualPath.StartsWith(dir.VirtualPath))
{
root = dir;
isContinue = true;
break;
}
} if (isContinue)
continue; // 如果都不是,那么,当前的 root 就是其父目录
return root;
}
} //是否存在目录
public override bool DirectoryExists(string virtualDir)
{
/// 从根目录开始递归寻找
bool result = SearchDirectory(this.root, virtualDir);
if (result)
{
return true;
}
return this.Previous.DirectoryExists(virtualDir);
} //搜索目录
private bool SearchDirectory(VirtualDirectory parent, string virtualDir)
{
if (parent.Name == virtualDir)
{
return true;
} foreach (VirtualDirectory child in parent.Directories)
{
bool result = SearchDirectory(child, virtualDir);
if (result)
{
return true;
}
}
return false;
} //判断文件是否存在
public override bool FileExists(string virtualPath)
{ //只检查压缩包的一级目录(有就有,没有就没有)
foreach (VirtualFile file in this.root.Files)
{
if (file.Name.Replace("//", "/") == virtualPath)
{
return true;
}
}
return this.Previous.FileExists(virtualPath);
} public override System.Web.Hosting.VirtualDirectory GetDirectory(string virtualDir)
{
VirtualDirectory dir = GetParentDirectory(virtualDir);
// 不存在的话,找到父目录,存在的话,找到自己。
bool exist = dir.VirtualPath == virtualDir;
if (exist)
{
return dir;
}
return this.Previous.GetDirectory(virtualDir);
} public override System.Web.Hosting.VirtualFile GetFile(string virtualPath)
{
//找到可能存在的目录
VirtualDirectory dir = GetParentDirectory(virtualPath); // 遍历查找
foreach (VirtualFile file in dir.Files)
{
if (file.VirtualPath == virtualPath)
{
return file;
}
} return this.Previous.GetFile(virtualPath);
} public override System.Web.Caching.CacheDependency GetCacheDependency(string virtualPath, System.Collections.IEnumerable virtualPathDependencies, DateTime utcStart)
{
// 由于采用了压缩文件,所以不生成缓存依赖对象
return null;
} private byte[] ReadAllBytes(System.IO.Stream stream, int size)
{
byte[] buffer = new byte[size];
int count = stream.Read(buffer, 0, size);
return buffer;
}
}
 

  虚拟目录与虚拟文件类:

 
    public class ZipVirtualDirectory : System.Web.Hosting.VirtualDirectory
{
//保存文件夹中包含的子项目的集合
//包括文件和子目录
private List<VirtualFileBase> items;
private List<VirtualFile> files;
private List<VirtualDirectory> directories;
private string name; public override System.Collections.IEnumerable Files { get { return this.files; } }
public override System.Collections.IEnumerable Children { get { return this.items; } }
public override System.Collections.IEnumerable Directories { get { return directories; } }
public override string Name { get { return base.Name; } } public ZipVirtualDirectory(string name) : base(name)
{
this.items = new List<VirtualFileBase>();
this.directories = new List<VirtualDirectory>();
this.files = new List<VirtualFile>(); this.name = name;
} // 在目录中增加一个项目
public void AddVirtualItem(VirtualFileBase item)
{
this.items.Add(item);
if (item.IsDirectory)
{
this.directories.Add(item as VirtualDirectory);
}
else
{
this.files.Add(item as VirtualFile);
}
}
} public class ZipVirtualFile : System.Web.Hosting.VirtualFile
{
public override string Name { get { return this.name; } } public override System.IO.Stream Open()
{
return new System.IO.MemoryStream(this.buffer);
} private string name;
private byte[] buffer; public ZipVirtualFile(string name, byte[] buffer) : base(name)
{
this.name = name;
this.buffer = buffer;
}
}
 

  注册虚拟目录提供程序,在App_Code目录里面添加一个AppStart类:

 
    public class AppStart
{
public static void AppInitialize()
{
ZipVirtualPathProvider virtualPathProvider = new ZipVirtualPathProvider();
System.Web.Hosting.HostingEnvironment.RegisterVirtualPathProvider(virtualPathProvider);
}
}
 

  然后新建一个zip压缩包,里面有如下两个页面:

  

  然后启动项目,打开路径:/test/1.html。

  

  网站程序中是不存在"test"这个目录的,但是自定义的虚拟目录将对此路径的访问映射到"test.zip"里面的1.html去了。这就是自定义虚拟路径提供器的强大之处。

Asp.net压缩网站中的文件的更多相关文章

  1. ASP.NET Web网站中App_Code文件夹的作用及使用场景

    原文地址:Web Site项目和ASP.NET Web Application中App_Code文件夹的作用作者:宾的宾 我现在要建一个ASP.NET的网站了,不难吧,开始动手.如下图: 这种方法建立 ...

  2. 使用PHP和GZip压缩网站JS/CSS文件加速网站访问速度

    使用PHP和GZip压缩网站JS/CSS文件加速网站访问速度 一些泛WEB 2.0网站为了追求用户体验,可能会大量使用CSS和JS文件.这就导致在服务器带宽一定的情况下,多用户并发访问速度变慢.如何加 ...

  3. 针对Linux ASP.NET MVC网站中 httpHandlers配置无效的解决方案

    近期有Linux ASP.NET用户反映,在MVC网站的Web.config中添加 httpHandlers 配置用于处理自定义类型,但是在运行中并没有产生预期的效果,服务器返回了404(找不到网页) ...

  4. 关于linux asp.net MVC网站中 httpHandlers配置无效的处理方法

    近期有Jexus用户反映,在Linux ASP.NET MVC网站的Web.config中添加 httpHandlers 配置用于处理自定义类型,但是在运行中并没有产生预期的效果,服务器返回了404( ...

  5. asp.net网站中增删文件夹会导致Session或cache等等丢失

    因为这会导致网站资源本身重新加载. 如果要改变文件和文件夹,一般应该是对 app_data 下进行操作.

  6. 在IIS7中ASP.NET MVC3网站中建立gcc编译服务时要注意的问题

    1. 正常配置下调用gcc总是失败,虽然在环境变量中配置了gcc路径,但提示找不到gcc编译程序: 2. 使用全路径调用gcc,也是失败,提示cc1.exe编译失败,失败代码53: 3. 通过远程桌面 ...

  7. asp.net(c#)开发中的文件上传组件uploadify的使用方法(带进度条)

    上文件传很常见,现在就文件上传利用HTML的File控件(uploadify)的,这里为大家介绍一下(uploadify)的一些使用方法.在目前Web开发中用的比较多的,可能uploadify(参考h ...

  8. 基础教程:上传/下载ASP.NET Core 2.0中的文件

    问题 如何上传和下载ASP.NET Core MVC中的文件. 解 在一个空的项目中,更新 Startup 类以添加MVC的服务和中间件. publicvoid ConfigureServices( ...

  9. [译]MVC网站教程(四):MVC4网站中集成jqGrid表格插件(系列完结)

    目录 1.   介绍 2.   软件环境 3.   在运行示例代码之前(源代码 + 示例登陆帐号) 4.         jqGrid和AJAX 5.         GridSettings 6.  ...

随机推荐

  1. 原 HttpClient 4.3超时设置

    https://my.oschina.net/u/577453/blog/173724 http://blog.csdn.net/zh521zh/article/details/51994140

  2. Day2:数据运算

    一.算数运算 如: #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Hiuhung Wan print(10%2) #求模(取模) # 0 ...

  3. 毕业两年做到测试经理的经历总结- 各个端的自动化,性能测试结合项目具体场景实战,分析客户反馈的Bug

    前言 最近看到行业的前辈都分享一些过往的经历来指导我们这些测试人员,我很尊敬我们的行业前辈,没有他们在前面铺路,如今我们这帮年轻的测试人估计还在碰壁或摸着石头过河,结合前辈们的经验,作为年轻的测试人也 ...

  4. 微服务实战(一):微服务架构的优势与不足 - DockOne.io

    原文:微服务实战(一):微服务架构的优势与不足 - DockOne.io [编者的话]本文来自Nginx官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战 ...

  5. 具体解释ebs接口之客户配置文件导入(二)

    ------------------------------------ -- 1a. Setup the Org_id ------------------------------------ ex ...

  6. Android Java Mail与Apache Mail发送邮件对比

    原文链接: 一.邮件简介  一封邮件由很多信息构成,主要的信息如下,其他的暂时不考虑,例如抄送等:  1.收件人:收件人的邮箱地址,例如xxx@xx.com  2.收件人姓名:大部分的邮件显示时都会显 ...

  7. MySQL的安装及使用教程

    MySQL的安装及使用教程 一.  MySQL的下载及安装 首先登陆MySQL的官网,选择Downloads→Windows→MySQL Installer→Windows(x86,32-bit),M ...

  8. Android 底部TabActivity(0)——开篇(界面分析|系列文章文件夹)

    当下主流的软件没有一个统一明白的风格,App框架什么样的都有,但个人钟情于页面底部Tab分签架构,移动设备的屏幕尽管越来越大,可是显示的内容还是有限,为了能展示很多其它的内容,方便简洁的操作习惯中Ta ...

  9. sqoop 1.4.4-cdh5.1.2快速入门 分类: C_OHTERS 2015-06-06 11:40 208人阅读 评论(0) 收藏

    一.快速入门 (一)下载安装 1.下载并解压 wget http://archive.cloudera.com/cdh5/cdh/5/sqoop-1.4.4-cdh5.1.2.tar.gz tar - ...

  10. go 字符串 数字 整型 浮点 转换

    import "strconv" //先导入strconv包 // string到int int, err := strconv.Atoi(string) // string到in ...