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

  这个东西是要需要通过实现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. 理解String的compareTo()方法返回值

    compareTo()的返回值是整型,它是先比较对应字符的大小(ASCII码顺序), 如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值. 如果第一个字符和参数的第一个字符相等,则以第 ...

  2. Java核心技术 卷Ⅰ 基础知识(4)

    第六章 接口与内部类 接口 特性 接口与抽象类 对象克隆 接口与回调 内部类 使用内部类访问对象状态 内部类的特殊语法规则 局部内部类 匿名内部类 静态内部类 代理 Class[] in=new Cl ...

  3. 单位转换 inch mm mil

    从上面看:英寸(inch)是最大的单位   其次是毫米(mm)  再次是密耳(mil)

  4. GO语言学习(十)Go 语言条件语句

    Go 语言提供了以下几种条件判断语句: 语句 描述 if 语句 if 语句 由一个布尔表达式后紧跟一个或多个语句组成. if...else 语句 if 语句 后可以使用可选的 else 语句, els ...

  5. opencv cvtColor dtype issue(error: (-215) )

    opencv cvtColor dtype issue(error: (-215) ) 更详细的错误信息如下,color.cpp:9710: error: (-215) depth == CV_8U ...

  6. JS数据结构第二篇---链表

    一.什么是链表 链表是一种链式存储的线性表,是由一组节点组成的集合,每一个节点都存储了下一个节点的地址:指向另一个节点的引用叫链:和数组中的元素内存地址是连续的相比,链表中的所有元素的内存地址不一定是 ...

  7. Arcgis engine 指定图层对要素进行创建、删除等操作

    Arcgis engine 指定图层创建点要素 在指定的图层上创建一个点要素,点要素的位置是通过X,Y坐标指定的,下面是具体的注释 .其中 和IFeatureClassWrite接口有关的代码不要好像 ...

  8. [CSS] Use CSS Counters to Create Pure CSS Dynamic Lists

    CSS counters let you create dynamic lists without JavaScript. In this lesson, we will create a multi ...

  9. 怎样在一个fragment or 随意类中操作还有一个fragment中的方法

    1 怎样在acitivty中运行fragment中的方法: 首先获得这个Fragment的对象 xxxFragment fragmentObject = (xxxFragment) getFragme ...

  10. spyder在虚拟机上运行内核一直崩溃

    可能的原因是因为虚拟机设置的内存过小了