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

  这个东西是要需要通过实现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. Day1:第一个python小程序

    Day1:第一个python小程序与开发工具Pycharm 一.Hello World C:\Users\wenxh>python Python 3.6.2 (v3.6.2:5fd33b5, J ...

  2. Java基础学习总结(31)——Java思维导图

  3. Oracle 排序问题(null带来的)

    null 导致排序有问题, 对于数字的,一定要用nvl来解决.

  4. Scala在挖财的应用实践--转载

    原文地址:http://www.infoq.com/cn/articles/scala-architecture-wacai 编者按:本文是根据ArchSummit大会上挖财资深架构师王宏江的演讲&l ...

  5. 微信浏览器跳转外部浏览器 app下载

    这个是摘抄的,具体抄的哪里我忘记了,作为记录 2019年5月14日 现在这个好像也不好用了,微信又提示建议下载qq浏览器什么的,显示一个红色感叹号,让用户产生怀疑,很鄙视tx error_report ...

  6. VSX(翻译)Moving Code Blocks Among Code Regions using VS 2010 Extensions

    Moving Code Blocks Among Code Regions using VS 2010 Extensions (翻译)使用VS 2010 扩展性将代码块移至Region区域中 Down ...

  7. 请求筛选模块被配置为拒绝包含 hiddenSegment 节的 URL 中的路径

    转自原文 请求筛选模块被配置为拒绝包含 hiddenSegment 节的 URL 中的路径. 打开C:\Windows\System32\inetsrv\config路径 找到applicationH ...

  8. POJ 3090 Visible Lattice Points (ZOJ 2777)

    http://poj.org/problem?id=3090 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1777 题目大意: ...

  9. [PReact] Reduce the Size of a React App in Two Lines with preact-compat

    Not every app is greenfield, and it would be a shame if existing React apps could not benefit from t ...

  10. FOJ (FZU) 1476 矩形的个数 排列组合。

    http://acm.fzu.edu.cn/problem.php?pid=1476  Problem Description 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1* ...