2

我对从 CF8 到 9 的更改视而不见,如果不创建自定义缓存或其他一些不值得努力的剧烈变通方法,就无法再写入磁盘缓存。

目前,我已经放弃尝试将应用程序转换为支持(如果可能)将缓存文件的内容写入静态 cfm 文件的相同方法。我现在更加好奇,因为我已经深入研究了它。我正在寻找比我自己更有经验的人。

我想了解或知道如何处理模板缓存的是:

  1. 能够在默认或自定义缓存中定位模板并刷新它而不清除整个缓存。
  2. 出于好奇或调试方法查看或解析特定缓存模板的内容。

这是我正在使用的代码,需要 CF 9.0.1,因为我相信由于添加了 EhCache 2.0,一些缓存功能在 9.0 中不可用。

<cftry>
        <cfcache action='serverCache' timeout='#CreateTimeSpan(0,0,0,10)#' stripwhitespace='true' 
                 usequerystring='true'>
            Stuff to cache.
            <br/>
            <cfoutput>#now()#</cfoutput>
            <br/>
        </cfcache>

        <!--- Get the cached contents --->
        <cfdump var="#cacheGetProperties()#">
        <cfdump var="#getAllTemplateCacheIds()#">
        <!---Locate a single cached item --->
        <cfscript>
            cacheArray = getAllTemplateCacheIds();
            WriteOutput("Before<br/>");
            for(i=1;i LTE ArrayLen(cacheArray);i=i+1)
            {
                writeOutput(cacheArray[i] & "<br/>");
                if(FindNoCase(scriptPath, cacheArray[i]))
                {
                    //expect only to find min and max one per string so no need to worry about out of bounds
                    cacheIDSubStr =  REFind("[a-fA-F\d]{32}(?=_LINE:\d*$)",cacheArray[i],1,1);
                    cacheID = Mid(cacheArray[i],CacheIDSubStr.pos[1],CacheIDSubStr.len[1]);
                   //Failure to delete cache expected fireworks
                    //WriteOutput(cacheID&"<br/>");
                    //cacheObject = CacheGet(cacheID);
                    //CacheRemove(cacheID);
                    templateCache = cacheGetSession("template");
                      //Tooling around with the exposed guts of cacheGetSession
                    WriteDump(templateCache.getKeys());
                }
            }
        </cfscript>
    <cfcatch type="Any">

        <cfscript>
            writeoutput("Error:" & cfcatch.message);
        </cfscript>

    </cfcatch>
    </cftry>

不应该存在错误,但它是从原始编辑到这里发布的。

4

1 回答 1

1

秘密在于 CF 9.0.1 函数cacheGetSession(),以及修改其他函数以将 akey作为参数。

以下代码仅适用于 9.0.1。

假设:

<cfcache action="serverCache" timeout="#CreateTimeSpan(0,0,0,10)#" stripwhitespace="true" usequerystring="true">
Stuff to cache in the default store.
<br/>
<cfoutput>#Now()#</cfoutput>
</cfcache>

<cfcache action="serverCache" key="myCustomCache" timeout="#CreateTimeSpan(0,0,0,10)#" stripwhitespace="true" usequerystring="true">
Stuff to cache in the 'myCustomCache' store.
<cfoutput>#Now()#</cfoutput>
</cfcache>

分别访问缓存的标识符

默认(模板):

<cfdump var=#getAllTemplateCacheIds()#>

我的自定义缓存:

<cfdump var=#cacheGetSession('myCustomCache',true).getKeys()#>

读取自定义缓存的数据

<cfset keys = cacheGetSession('myCustomCache',true).getKeys() />

<cfcache key="myCustomCache" action="get" name="dataInCache" id="#keys[1]#">

<cfdump var=#dataInCache#>

独立于默认值刷新自定义缓存

<cfset cacheRemove(keys[1],true,'myCustomCache')>

遗憾的是,关于 9.0.1 中的功能,文档并不是最好的。幸运的是,CF 用户群擅长挖掘这些东西,即Rob-Brooks Bilson,他有许多关于 CF 和一般缓存的精彩文章。

在以这种方式使用缓存时,您应该记住几个注意事项:

  1. 这些调用在底层与 EhCache 相关联,即 Java,如果您尝试访问不存在的键,则可能会返回 NULL。将您的结果包装起来IsNull()以进行验证。

  2. cacheGetSession() 具有误导性(正如 Rob 在他的博客中指出的那样),您可能认为您正在检索与会话相关的缓存数据,因为它适用于您的应用程序,但事实并非如此——它是服务器范围的,您将在共享应用程序环境中查看其他缓存的键。

因此,请注意刷新适当的数据...

于 2012-03-21T03:24:22.787 回答