zoukankan      html  css  js  c++  java
  • Asp.net压缩网站中的文件

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

      这个东西是要需要通过实现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去了。这就是自定义虚拟路径提供器的强大之处。

  • 相关阅读:
    shell脚本模拟交互操作实现上传文件至sftp
    从文件A中去除掉文件B的内容
    Linux批量kill某个程序的进程
    单数据盘或者很多数据盘mount挂载到某个目录
    用户HTTP请求过程简单剖析
    linux服务器系统盘坏且系统盘为软raid的修复方法
    linux系统运行状态检查
    TCP的三次握手和四次挥手
    ES6嵌套对象的解构
    DRF框架在嵌套关系下实现嵌套对象字段的过滤
  • 原文地址:https://www.cnblogs.com/jameslif/p/4966768.html
Copyright © 2011-2022 走看看