页面缓存技术 与 利用静态类和FileSystemWatcher自动生成静态页面模板

使用@ OutputCache指令

使用@ OutputCache指令,能够实现对页面输出缓存的一般性需要。@ OutputCache指令在https://www.360docs.net/doc/0e14838757.html,页或者页中包含的用户控件的头部声明。这种方式非常方便,只需几个简单的属性设置,就能够实现页面的输出缓存 策略。@ OutputCache指令声明代码如下。


@ OutputCache指令代码

<%@ OutputCache CacheProfile =" " NoStore= "True | False" Duration ="#ofseconds" Shared ="True | False" Location ="Any | Client | Downstream | Server | None | ServerandClient " SqlDependency ="database/table name pair | CommandNotification " VaryByControl ="controlname" VaryByCustom ="browser | customstring" VaryByHeader ="headers" VaryByParam ="parametername" %>

如上所示,在@ OutputCache指令中,共包括10个属性,它们是CacheProfile、NoStore、Duration、Shared、 Location、SqlDependency、VaryByControl、VaryByCustom、VaryByHeader和 VaryByParam。这些属性将对缓存时间、缓存项的位置、SQL数据缓存依赖等各方面进行设置。下面简要介绍以上属性的基本概念。

CacheProfile

用于定义与该页关联的缓存设置的名称。是可选属性,默认值为空字符("")。需要注意的是,包含在用户控件中的@ OutputCache指令不支持此属性。在页面中指定此属性时,属性值必须与Web.config文件<outputCacheSettings>配置 节下的outputCacheProfiles元素中的一个可用项的名称匹配。如果此名称与配置文件项不匹配,将引发异常。

NoStore

该属性定义一个布尔值,用于决定是否阻止敏感信息的二级存储。需要注意的是,包含在用户控件中的@ OutputCache指令不支持此属性。将此属性设置为true等效于在请求期间执行代码“Response.Cache.SetNoStore();”。

Duration

用于设置页面或者用户控件缓存的时间。单位是秒。通过设置该属性,能够为来自对象的HTTP响应建立了一个过期策略,并将自动缓存页或用户控件输出。需要注意的是,Duration属性是必需的,否则将会引起分析器错误。

Shared

该属性定义一个布尔值,用于确定用户控件输出是否可以由多个页共享。默认值为false。注意,包含在https://www.360docs.net/doc/0e14838757.html,页中的@ OutputCache指令不支持此属性。

Location

用于指定输出缓存项的位置。其属性值是OutputCacheLocation枚举值,它们是Any、Client、Downstream、None、 Server和ServerAndClient。默认值是Any,表示输出缓存可用于所有请求,包括客户端浏览器、代理服务器或处理请求的服务器上。需要注意的是,包含在用户控件中的@ OutputCache指令不支持此属性。

SqlDependency

该属性标识一组数据库/表名称对的字符串值,页或控件的输出缓存依赖于这些名称对。需要注意:SqlCacheDependency类监视输出缓存所依赖 的数据库中的表,因此,当更

新表中的项时,使用基于表的轮询将从缓存中移除这些项。当通知(在SQL Server 2005中)与CommandNotification值一起使用时,最终将使用SqlDependency类向SQL Server 2005服务器注册查询通知。另外,SqlDependency属性的CommandNotification值仅在https://www.360docs.net/doc/0e14838757.html,页中有效。控件只能将 基于表的轮询用于@ OutputCache指令。

VaryByControl

该属性使用一个分号分隔的字符串列表来更改用户控件的输出缓存。这些字符串代表在用户控件中声明的https://www.360docs.net/doc/0e14838757.html,服务器控件的ID属性值。除非已经包含了VaryByParam属性,否则在@ OutputCache指令中,该属性是必需的。

VaryByCustom

用于自定义输出缓存要求的任意文本。如果赋予该属性值是browser,缓存将随浏览器名称和主要版本信息的不同而异。如果输入了自定义字符串,则必须在 应用程序的Global.asax文件中重写HttpApplication.GetVaryByCustomString方法。

VaryByHeader

该属性中包含由分号分隔的HTTP标头列表,用于使输出缓存发生变化。当将该属性设为多标头时,对于每个指定的标头,输出缓存都包含一个请求文档的不同版 本。VaryByHeader属性在所有HTTP 1.1缓存中启用缓存项,而不仅限于https://www.360docs.net/doc/0e14838757.html,缓存。用户控件中的@ OutputCache指令不支持此属性。

VaryByParam

该属性定义了一个分号分隔的字符串列表,用于使输出缓存发生变化。默认情况下,这些字符串与用GET方法属性发送的查询字符串值对应,或与用POST方法 发送的参数对应。当将该属性设置为多参数时,对于每个指定的参数,输出缓存都包含一个请求文档的不同版本。可能的值包括“none”、“*”和任何有效的 查询字符串或POST参数名称。值得注意的是,在输出缓存https://www.360docs.net/doc/0e14838757.html,页时,该属性是必需的。它对于用户控件也是必需的,除非已经在用户控件的@ OutputCache指令中包含了VaryByControl属性。如果没有包含,则会发生分析器错误。如果不需要使缓存内容随任何指定参数发生变化, 则可将该值设为“none”。如果要使输出缓存根据所有参数值发生变化,则将属性设置为“*”。















利用静态类和FileSystemWatcher自动生成静态页面模板 - 程序开发 - https://www.360docs.net/doc/0e14838757.html,教程


这里我利用静态类和FileSystemWatcher实现网页模板的提取功能。

利用静态类和FileSystemWatcher实现有以下优点:
1、模板存放在内存中读取方便,提高读取速度。
2、动态监视模板改动,模板实时更新。
3、通过一个XML文件作为模板管理,简单,方便。
4、所有模板保存为单独文件方便修改。

最优应用:
由事件驱动自动生成静态页面或者直接根据数据内容生成静态页面。
例如:
1、定时抓取一些网站的内容

。(PS:看到好多网站在抓Cnblogs的信息,我并不希望这些网站利用这个方法。)
2、实时新闻信息生成。
3、信息源驱动信息生成。

提取方法:
GetTemplateByKey(模板key);

注意事项:
1、模板列表XML文件最好更改后缀名,这样防止其他人直接访问XML文件得到您的列表。
2、模板文件也最好更改后缀名,这样防止其他人直接访问HTML文件得到您的模板。

模板调用类代码
cs --------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Data;
using System.Web;

namespace Xingmai..Template
{
///


/// Html模板调用
///

public static class HtmlCollection
{
///
/// 模板表
///

private static DataTable Collection = new DataTable();

///
/// 模板目录
///

private static string strTemplatePath;
#region 静态构造函数

static HtmlCollection()
{
LoadTemplates();
}

#endregion

///
/// 初始化数据表并设置文件监视
///

private static void LoadTemplates()
{
strTemplatePath = HttpContext.Current.Server.MapPath("~/TemplateDir/HtmlTemplate/");
FileSystemWatcher watcher = new FileSystemWatcher(strTemplatePath, "*.*");
watcher.NotifyFilter = https://www.360docs.net/doc/0e14838757.html,stAccess | https://www.360docs.net/doc/0e14838757.html,stWrite | NotifyFilters.FileName | NotifyFilters.Size;
watcher.IncludeSubdirectories = true;
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
LoadTemplateData();
watcher.EnableRaisingEvents = true;
}

///
/// 更新数据
///

private static void LoadTemplateData()
{
lock (Collection)
{
DataSet ds = new DataSet();
ds.ReadXml(string.Format("{0}Template.List", strTemplatePath));
if (Collection != null)
{
Collection = null;
}
Collection = ds.Tables[0];
Collection.Columns.Add("Content");
string strTemplateFilePath = strTemplatePath + @"Template\";
foreach (DataRow dr in Collection.Rows)
{
using (TextReader reader = new StreamReader(string.Format("{0}{1}", strTemplateFilePath, dr["File"].ToString())))
{
dr["Content"] = reader.ReadToEnd();
}

}
}
}

///
/// 如果文件夹有改变
///

///
///
static void watcher_Changed(object sender, FileSystemEventArgs e)
{
LoadTemplateData();
}

///
/// 通过Key获取相应的模板
///

///
///

turns>
public static string GetTemplateByKey(string strKey)
{




lock (Collection)
{
DataView dv = Collection.DefaultView;
dv.RowFilter = string.Format("Key='{0}'", strKey);
if (dv.Count == 0)
return "";
else
return dv[0]["Content"].ToString();
}
}
}
}


xml 文件(根据自己的需要添加字段,如果模板较多可以添加分类字段)-----------------------------------------------------

---


1
1
1.html


关于FileSystemWatcher (MSDN)

侦听文件系统更改通知,并在目录或目录中的文件发生更改时引发事件。

使用 FileSystemWatcher 监视指定目录中的更改。可监视指定目录中的文件或子目录的更改。可以创建一个组件来监视本地计算机、

网络驱动器或远程计算机上的文件。

若要监视所有文件中的更改,请将 Filter 属性设置为空字符串 ("") 或使用通配符(“*.*”)。若要监视特定的文件,请将 Filter

属性设置为该文件名。例如,若要监视文件 MyDoc.txt 中的更改,请将 Filter 属性设置为“MyDoc.txt”。也可以监视特定类型文件

中的更改。例如,若要监视文本文件中的更改,请将 Filter 属性设置为“*.txt”。

可监视目录或文件中的若干种更改。例如,可监视文件或目录的 Attributes、LastWrite 日期和时间或 Size 方面的更改。通过将

NotifyFilter 属性设置为 NotifyFilters 值之一来达到此目的。有关可监视的更改类型的更多信息,请参见 NotifyFilters。

可监视文件或目录的重命名、删除或创建。例如,若要监视文本文件的重命名,请将 Filter 属性设置为“*.txt”,并使用为其参数

指定的 Renamed 来调用 WaitForChanged 方法。

Windows 操作系统在 FileSystemWatcher 创建的缓冲区中通知组件发生文件更改。如果短时间内有很多更改,则缓冲区可能会溢出。

这将导致组件失去对目录更改的跟踪,并且它将只提供一般性通知。使用 InternalBufferSize 属性来增加缓冲区大小的开销较大,因

为它来自无法换出到磁盘的非页面内存,所以应确保缓冲区大小适中(尽量小,但也要有足够大小以便不会丢失任何文件更改事件)。

若要避免缓冲区溢出,请使用 NotifyFilter 和 IncludeSubdirectories 属性,以便可筛选掉不想要的更改通知。

有关 FileSystemWatcher 的实例的初始属性值列表,请参见 FileSystemWatcher 构造函数。

使用 FileSystemWatcher 类时,请注意以下事项。

不忽略隐藏文件。

在某些系统中,FileSystemWatcher 使用 8.3 短文件名格式报告文件更改

。例如,对“LongFileName.LongExtension”的更改可能报

告为“LongFi~.Lon”。

此类在类级别上包含一个链接要求和一个继承要求,这两个要求应用于所有成员。如果直接调用方或派生类不具有完全信任权限,则会

引发 SecurityException。有关安全要求的详细信息,请参见 链接要求。

事件和缓冲区大小
请注意,有几个因素可能影响引发哪些文件系统更改事件,如下所述:

公共文件系统操作可能会引发多个事件。例如,将文件从一个目录移到另一个目录时,可能会引发若干 OnChanged 以及一些

OnCreated 和 OnDeleted 事件。移动文件是一个包含多个简单操作的复杂操作,因此会引发多个事件。同样,一些应用程序(如反病

毒软件)可能导致被 FileSystemWatcher 检测到的附加文件系统事件。

只要磁盘没有切换或移除,FileSystemWatcher 就可监视它们。因为 CD 和 DVD 的时间戳和属性不能更改,所以 FileSystemWatcher

不为 CD 和 DVD 引发事件。要使该组件正常运行,远程计算机必须具有所需的这些平台之一。但是,无法从 Windows NT 4.0 计算机

监视远程 Windows NT 4.0 计算机。

在 Windows XP(Service Pack 1 之前版本)或者 Windows 2000 SP2 或更低版本中,如果多个 FileSystemWatcher 对象正在监视同

一个 UNC 路径,则只有其中一个对象会引发事件。在运行 Windows XP SP1 及之后版本、Windows 2000 SP3 或之后版本或者 Windows

Server 2003 的计算机上,所有 FileSystemWatcher 对象都将引发相应的事件。

设置 Filter 不会减少进入缓冲区中的内容。

请注意,由于 Windows 操作系统的依赖项,当丢失某个事件或超出缓冲区大小时,FileSystemWatcher 不会引发 Error 事件。若要防





止丢失事件,请遵从这些准则:

使用 InternalBufferSize 属性增加缓冲区大小可以防止丢失文件系统更改事件。

避免监视带有长文件名的文件。考虑使用较短的名称进行重命名。

尽可能使事件处理代码短小。

示例
下面的示例创建 FileSystemWatcher 来监视运行时指定的目录。组件设置为监视 LastWrite 和 LastAccess 时间方面的更改,以及目

录中文本文件的创建、删除或重命名。如果更改、创建或删除文件,文件路径将被输出到控制台。在文件重命名后,旧路径和新路径都

输出到控制台。

在此示例中使用 System.Diagnostics 和 System.IO 命名空间。

public class Watcher
{

public static void Main()
{
Run();

}

[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
public static void Run()
{
str

ing[] args = System.Environment.GetCommandLineArgs();

// If a directory is not specified, exit program.
if(args.Length != 2)
{
// Display the proper way to call the program.
Console.WriteLine("Usage: Watcher.exe (directory)");
return;
}

// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = args[1];
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = https://www.360docs.net/doc/0e14838757.html,stAccess | https://www.360docs.net/doc/0e14838757.html,stWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";

// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);

// Begin watching.
watcher.EnableRaisingEvents = true;

// Wait for the user to quit the program.
Console.WriteLine("Press \'q\' to quit the sample.");
while(Console.Read()!='q');
}

// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}

private static void OnRenamed(object source, RenamedEventArgs e)
{
// Specify what is done when a file is renamed.
Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
}
}



































思路

1. 利用如Dw-Mx这样的工具生成html格式的模板,在需要添加格式的地方加入特殊标记(如$htmlformat$),动态生成文件时利用代码读取此模板,然后获得前台输入的内容,添加到此模板的标记位置中,生成新文件名后写入磁盘,写入后再向数据库中写入相关数据。

2. 使用后台代码硬编码Html文件,可以使用HtmlTextWriter类来写html文件。

优点

1. 可以建立非常复杂的页面,利用包含js文件的方法,在js文件内加入document.write()方法可以在所有页面内加入如页面头,广告等内容。

2. 静态html文件利用MS Windows2000的Index Server可以建立全文搜索引擎,利用https://www.360docs.net/doc/0e14838757.html,可以以DataTable的方式得到搜索结果。而Win2000的Index服务无法查找xml文件的内容。如果包括了数据库搜索与Index索引双重查找,那么此搜索功能将非常强大。

3. 节省服务器的负荷,请求一个静态的html文件比一个aspx文件服务器资源节省许多。

缺点

思路二: 如果用硬编码的方式,工作量非常大

,需要非常多的html代码。调试困难。而且使用硬编码生成的html样式无法修改,如果网站更换样式,那么必须得重新编码,给后期带来巨大的工作量。

因此这里采用的是第一种思路

示列代码

1.定义(template.htm)html模板页面

<html>

<head>

<title></title>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">

</head>

<body >

<table $htmlformat[0] height="100%" border="0" width="100%" cellpadding="10" cellspacing="0" bgcolor="#eeeeee" style="border:1px solid #000000">

<tr>

<td width="100%" valign="middle" align="left">

<span style="color: $htmlformat[1];font-size: $htmlformat[2]">$htmlformat[3]</span>

</td>

</tr>

</table>

</body>

</html>

https://www.360docs.net/doc/0e14838757.html,代码:

//---------------------读html模板页面到stringbuilder对象里----

string[] format=new string[4];//定义和htmlyem标记数目一致的数组

StringBuilder htmltext=new StringBuilder();

try

{

using (StreamReader sr = new StreamReader("存放模板页面的路径和页面名"))

{

String line;

while ((line = sr.ReadLine()) != null)

{

htmltext.Append(line);

}

sr.Close();

}

}

catch

{

Response.Write("<Script>alert('读取文件错误')</Script>");

}

//---------------------给标记数组赋值------------

format[0]="background="bg.jpg"";//背景图片

format[1]= "#990099";//字体颜色

format[2]="150px";//字体大小

format[3]= "<marquee>生成的模板html页面</marquee>";//文字说明

//----------替换htm里的标记为你想加的内容

for(int i=0;i<4;i++)

{

htmltext.Replace("$htmlformat["+i+"]",format[i]);

}

//----------生成htm文件------------------――

try

{

using(StreamWriter sw=new StreamWriter("存放路径和页面名",false,System.Text.Encoding.GetEncoding("GB2312")))

{

sw.WriteLine(htmltext);

sw.Flush();

sw.Close();

}

}

catch

{

Response.Write ("The file could not be wirte:");

}

小结

用此方法可以方便的生成html文件。程序使用了是循环替换,因此对需替换大量元素的模板速度非常快。




相关文档
最新文档