惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

I
Intezer
Google DeepMind News
Google DeepMind News
有赞技术团队
有赞技术团队
博客园 - Franky
Jina AI
Jina AI
博客园_首页
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Engineering at Meta
Engineering at Meta
B
Blog
A
About on SuperTechFans
J
Java Code Geeks
WordPress大学
WordPress大学
GbyAI
GbyAI
N
News | PayPal Newsroom
C
Cybersecurity and Infrastructure Security Agency CISA
博客园 - 聂微东
Stack Overflow Blog
Stack Overflow Blog
T
The Exploit Database - CXSecurity.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
Netflix TechBlog - Medium
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Palo Alto Networks Blog
U
Unit 42
Vercel News
Vercel News
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Know Your Adversary
Know Your Adversary
博客园 - 三生石上(FineUI控件)
AWS News Blog
AWS News Blog
Latest news
Latest news
V
V2EX
Y
Y Combinator Blog
Scott Helme
Scott Helme
博客园 - 叶小钗
美团技术团队
A
Arctic Wolf
S
Secure Thoughts
H
Help Net Security
L
LangChain Blog
博客园 - 司徒正美
V2EX - 技术
V2EX - 技术
P
Proofpoint News Feed
M
MIT News - Artificial intelligence
I
InfoQ
Cyberwarzone
Cyberwarzone
S
SegmentFault 最新的问题
Hacker News - Newest:
Hacker News - Newest: "LLM"

博客园 - refuly

【半原创】将js和css文件装入localStorage加速程序执行 SqlAgent备份脚本 ASP.net 使用HttpHandler实现图片防盗链 提取HTML代码中文字的C#函数 - refuly - 博客园 水晶头的制作 解决ASP.NET“类型初始值设定项引发异常” 解决vs2005 经WebDeployment发布后 global.asax 事件不启动 C# 实现Epson热敏打印机打印 Pos机用 去掉文件名中的非法字符 - refuly - 博客园 window.onbeforeunload与window.onunlad对比 HttpModule通过修改CSS切换皮肤 asp.net Excel导入&导出 - refuly - 博客园 计算机端口的介绍 Sql Server数据导出EXCEL 获取字符串的真实长度 c# 小数位数处理 新旧身份证合法性验证及验证算法 C#进制转换 Asp.net 备份、还原Ms SQLServer及压缩Access数据库
用Response.Filter生成静态页[要注意并发问题]
refuly · 2009-05-29 · via 博客园 - refuly
using System.IO;

namespace URLRewriter
{
    /// <summary>
    /// 生成htm静态页面
    /// </summary>
    public class ResponseFilter : Stream
    {
        private Stream m_sink;
        private long m_position;
        private FileStream fs;

        public ResponseFilter(Stream sink, string filePath)
        {
            m_sink = sink;
            fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
        }

        // The following members of Stream must be overriden.
        public override bool CanRead
        { get { return true; } }

        public override bool CanSeek
        { get { return false; } }

        public override bool CanWrite
        { get { return false; } }

        public override long Length
        { get { return 0; } }

        public override long Position
        {
            get { return m_position; }
            set { m_position = value; }
        }

        public override long Seek(long offset, System.IO.SeekOrigin direction)
        {
            return 0;
        }

        public override void SetLength(long length)
        {
            m_sink.SetLength(length);
        }

        public override void Close()
        {
            m_sink.Close();
            fs.Close();
        }

        public override void Flush()
        {
            m_sink.Flush();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return m_sink.Read(buffer, offset, count);
        }

        // Override the Write method to filter Response to a file.
        public override void Write(byte[] buffer, int offset, int count)
        {
            //Write out the response to the browser.
            m_sink.Write(buffer, 0, count);

            //Write out the response to the file.
            fs.Write(buffer, 0, count);
        }
    }
}

上边的这个类在生成静态页的时候,如果.net解析代码时,遇到错误,它依然会生成一个静态页面,而且这个静态页面在程序运行结束的时候,还处于打开状态。

显然这是我们不愿意看到的,而且这个类还不支持并发操作,如果和某一页面的关联的静态页失效了,假定这时候有两个用户同时访问这个页面,其中一个用户正在向静态页面写入数据,另外一个用户却需要访问这个已被别人打开的页面,系统同样会出现错误。基于这两个问题,我把这个类修改成下边的样子,就可以解决上述问题了。

using System.IO;
using System.Web;

namespace URLRewriter
{
    /// <summary>
    /// 生成htm静态页面
    /// </summary>
    public class ResponseFilter : Stream
    {
        private Stream m_sink;
        private long m_position;
        private FileStream fs;
        private string filePath = string.Empty;

        public ResponseFilter(Stream sink, string filePath)
        {
            this.m_sink = sink;
            this.filePath = filePath;
        }

        // The following members of Stream must be overriden.
        public override bool CanRead
        { get { return true; } }

        public override bool CanSeek
        { get { return false; } }

        public override bool CanWrite
        { get { return false; } }

        public override long Length
        { get { return 0; } }

        public override long Position
        {
            get { return m_position; }
            set { m_position = value; }
        }

        public override long Seek(long offset, System.IO.SeekOrigin direction)
        {
            return 0;
        }

        public override void SetLength(long length)
        {
            this.m_sink.SetLength(length);
        }

        public override void Close()
        {
            this.m_sink.Close();
            this.fs.Close();
        }

        public override void Flush()
        {
            this.m_sink.Flush();
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return m_sink.Read(buffer, offset, count);
        }

        // Override the Write method to filter Response to a file.
        public override void Write(byte[] buffer, int offset, int count)
        {
            //首先判断有没有系统错误
            if (HttpContext.Current.Error == null)
            {
                try
                {
                    if (fs == null)
                        this.fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
                    //将数据写入静态文件.
                    this.fs.Write(buffer, 0, count);
                }
                catch
                {
                    if (fs != null)
                    {
                        //关闭流
                        this.fs.Close();
                        //删除静态页面
                        if (File.Exists(filePath))
                        {
                            File.Delete(filePath);
                            return;
                        }
                    }
                }
            }
            //Write out the response to the browser.
            this.m_sink.Write(buffer, 0, count);
        }
    }
}


修改的地方是构造函数和这个方法(public override void Write(byte[] buffer, int offset, int count)),调用的方法分为两种,一种是在页面级别的调用,示例如下:

protected override void OnInit(EventArgs e)
{
    if (!this.IsPostBack)
    {
        string filePath = this.Server.MapPath(Common.AppName) + "\\index.htm";
        Response.Filter = new AspNetFilter(Response.Filter, filePath);
    }
    base.OnInit(e);
}


重写Page类的OnInit方法