Operation
You can optimize your ColdFusion application in many ways. Optimizing ColdFusion mostly involves good development and coding practices. For example, good database design and usage is a prime contributor to efficient ColdFusion applications.
In many other topics, the optimization techniques provided are pertinent to the related ColdFusion topic. The following information is about general ColdFusion optimization tools and strategies, and particularly about using CFML caching tags for optimization. There is also information on optimizing database use, an important area for application optimization.
The ColdFusion Administrator provides caching options for ColdFusion pages and SQL queries. For information on these options, see the ColdFusion Administrator online Help and Configuring and Administering ColdFusion.
For information on debugging techniques that help you identify slow pages, see Debugging and Troubleshooting Applications.
For additional information on optimizing ColdFusion, see the Adobe ColdFusion support center at www.adobe.com/go/learn_cfu_support_en.
Caching ColdFusion pages that change infrequently
Some ColdFusion pages produce output that changes infrequently. For example, if you have an application that extracts a vendor list from a database or produces a quarterly results summary. Normally, when ColdFusion gets a request for a page in the application, it does all the business logic and display processing that are required to produce the report or generate and display the list. If the results change infrequently, it is an inefficient use of processor resources and bandwidth.
The cfcache tag tells ColdFusion to cache the HTML that results from processing a page request in a temporary file on the server. This HTML need not be generated each time the page is requested. When ColdFusion gets a request for a cached ColdFusion page, it retrieves the pregenerated HTML page without having to process the ColdFusion page. ColdFusion can also cache the page on the client. If the client browser has its own cached copy of the page from a previous viewing, ColdFusion instructs the browser to use the client's page rather than resending the page.
The cfcache tag caching mechanism considers that each URL is a separate page. Therefore, http://www.mySite.com/view.cfm?id=1 and http://www.mySite.com/view.cfm?id=2 result in two separate cached pages. Because ColdFusion caches a separate page for each unique set of URL parameters, the caching mechanism accommodates pages for which different parameters result in different output. |
Using the cfcache tag
You tell ColdFusion to cache the page results by placing a cfcache tag on your ColdFusion page before code that outputs text. The tag lets you specify the following information:
- Whether to cache the page results on the server, the client system, or both. The default is both. The default is optimal for pages that are identical for all users. If the pages contain client-specific information, or are secured with ColdFusion user security, set the action attribute in the cfcache tag to ClientCache.
- The directory on the server in which to store the cached pages. The default directory is cf_root/cache. It is a good practice to create a separate cache directory for each application. Doing so prevents the cfcache tag flush action from inappropriately flushing more than one application's caches at a time.
- The time span that indicates how long the page lasts in the cache from when it is stored until it is automatically flushed.
You can also specify several attributes for accessing a cached page on the web server, including a user name and password (if required by the web server), the port, and the protocol (HTTP or HTTPS) to use to access the page.
Place the cfcache tag before any code on your page that generates output, typically at the top of the page body. For example, the following tag tells ColdFusion to cache the page on both the client and the server. On the server, the page is cached in the e:/temp/page_cache directory. ColdFusion retains the cached page for one day.
<cfcache timespan="#CreateTimespan(1, 0, 0, 0)#" directory="e:/temp/page_cache">
If an Application.cfm or Application.cfc page displays text (for example, if it includes a header page), use the cfcache tag on the Application.cfm page, in addition to the pages that you cache. Otherwise, ColdFusion displays the Application.cfm page output twice on each cached page.
Flushing cached pages
ColdFusion automatically flushes any cached page if you change the code on the page. It also automatically flushes pages after the expiration time span passes.
Use the cfcache tag with the action="flush" attribute to immediately flush one or more cached pages. You can optionally specify the directory that contains the cached pages to be flushed and a URL pattern that identifies the pages to flush. If you do not specify a URL pattern, all pages in the directory are flushed. The URL pattern can include asterisk (*) wildcards to specify parts of the URL that can vary.
When you use the cfcache tag to flush cached pages, ColdFusion deletes the pages cached on the server. If a flushed page is cached on the client system, it is deleted, and a new copy gets cached the next time the client tries to access the ColdFusion page.
The following example flushes all the pages in the e:/temp/page_cache/monthly directory that start with HR:
<cfcache action="flush" directory="e:/temp/page_cache/monthly" expirURL="HR*">
If you have a ColdFusion page that updates data that you use in cached pages, the page that does the updating includes a cfcache tag that flushes all pages that use the data.
For more information on the cfcache tag, see the CFML Reference.
Caching parts of ColdFusion pages
In some cases, your ColdFusion page contains a combination of dynamic information that ColdFusion must generate each time it displays the page, and information that it generates dynamically, but that changes less frequently. ColdFusion 9 provides granular control over caching. You can cache fragments of page that lets you cache the infrequently changed content.The following example illustrates fragment caching:
<cf output> W elcome to our home page.<br> The time is #TimeFormat(Now())#.<br> Your lucky number is: #RandRa nge(1,1000)#<br> <hr> </cfoutput> <!--- If the flag is false, query the DB, and save an image of the results output to a variable. ---> <cfcache action="optimal" timespan="#createtimespan(0,1,0,0)#" idletime="#createtimespan(0,0,30,0)#"><!--- Perform database query. ---><cfquery dataSource="cfartgallery" name="specialQuery"> SELECT * from art </cfquery> <!--- Calculate sale price and display the results. ---> <h2>Check out the following specials</h2> <table> <cfoutput query="specialQuery"> <tr> <td>#artid#</td> <td>#Description#</td> <td>#price#</td> </tr> </cfoutput> </table></cfcache><hr><p>Thank you for visiting us!</p>
In this example, the highlighted code creates a page fragment that displays all art records from the table art. The cache is set to expire either after one hour or after an idle time of 30 minutes. After the cache is invalidated, cache is recreated the next time the page is accessed thereby displaying updated information (if any).
Caching enhancements in ColdFusion 10
Application-specific caching
You can specify caching at server-level or specific to an application.
To set up cache configuration at the application level, specify the application-specific cache settings file (ehcache.xml) in the Application.cfc as shown in the following examples:
Specify the full path:
this.cache.configfile = "c:/cachesettings/ehcache.xml";
Specify the relative path with respect to the Application.cfc:
this.cache.configfile = "ehcache.xml";
If caching is specified at the application level, all cache functions use the application-specific cache configuration.
Example
Application.cfc
<cfscript> this.name = "appSpecificCacheTest"; this.cache.configfile = "ehcache.xml"; this.applicationTimeout = createtimespan(0,0,0,5); function onApplicationStart(){ writelog("In onApplicationStart()"); } function onApplicationEnd(){ writelog("In onApplicationEnd()"); } </cfscript> </cfcomponent>
cache.cfm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>cfhttp</title> </head> <!--- End of header ---> <body> <!--- remove object from Application Specific cache ---> <cfif ArrayLen(cacheGetAllIds()) gt 0> <cfset cacheRemove(ArrayToList(cacheGetAllIds()))> </cfif> <cfset obj1 = structNew()> <cfset obj1.name = "xyz"> <cfoutput>Starting to write to cache..</cfoutput> <cfset cachePut("obj1",obj1)> <br/> <cfoutput>Done!!</cfoutput> <cfoutput>Trying to fetch cached item...</cfoutput> <cfset obj = cacheGet("obj1")> <br/> <cfdump var="#obj#"> <cfscript> sleep(15000); </cfscript> <cfoutput>Trying to fetch cached item after 15 seconds...<br/></cfoutput> <cfset obj = cacheGet("obj1")> <cfdump var="#obj#"> </body> </html>
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> <diskStore path="java.io.tmpdir"/> <cacheManagerEventListenerFactory class="" properties=""/> <defaultCache maxElementsInMemory="5" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="5" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10" diskPersistent="false" diskExpiryThreadIntervalSeconds="3600" memoryStoreEvictionPolicy="LRU" clearOnFlush="true" /> <cache name="app1cache" maxElementsInMemory="5" eternal="false" timeToIdleSeconds="60" timeToLiveSeconds="5" overflowToDisk="false" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10" diskPersistent="false" diskExpiryThreadIntervalSeconds="3600" memoryStoreEvictionPolicy="LRU" clearOnFlush="true"/> </ehcache>
Enhanced query caching using Ehcache
Uses Ehcache
All cache queries are cached using Ehcache.
Default and custom query cache regions
All cache queries are stored in the default query region. There are independent default query regions for server-specific and application-specific cache. You can specify user-defined query cache region using the attribute cacheRegion in cfquery.If you do not specify a query cache region, the default cache region is used at application or server level (whichever is applicable).
Cache ID
You can associate a query with a unique identifier for each cache using the attribute cacheID. The ID you specify can be quoted while using the cache functions.Within cache, queries are stored as type query like object and template caches.
Fallback to internal cache
To fall back to internal cache (and not use Ehcache) to cache queries, do either of the following:
- Server level: Change the following setting: Check the option Use internal cache to store queries.
- Application level: Specify true for the following setting:this.cache.useinternalquerycache=true|false. The default value is false.
Specifying query limit
To specify a limit for maximum number of queries in cache, specify the number of queries in the Application.cfc for the following setting:this.cache.querysize
Using Amazon S3 storage
ColdFusion customers can now store data in Amazon S3. The support is extended across almost all tags and functions that take file or directory as input or output.
Storing files in Amazon S3 can be performed in the same manner as storing files on disk. Use a prefix s3:// to indicate that the files reside on Amazon S3. For example, s3://testbucket/sample.txt.
Amazon S3
For using Amazon S3, ColdFusion user must have an S3 account with Amazon.
For concepts and details related to Amazon S3, see the [AmazonS3
Documentation|http://aws.amazon.com/documentation/].
Accessing Amazon S3
Use either of the following URL formats to access Amazon S3 from ColdFusion:
s3://bucket/x/y/sample.txt}}Here, {{bucketis the name of the bucket and the remaining portion of the URL is the key name of the Amazon S3 object. In this case, specify the following authentication information in the Application.cfc:
this.name ="Object Operations"; this.s3.accessKeyId = "key_ID"; this.s3.awsSecretKey = "secret_key"; this.s3.defaultLocation="location"; </cfscript>
For example,<cffile action="write" output="S3 Specification" file="s3://testbucket/sample.txt"/>
- s3://accessKeyId:awsSecretKey@bucket/x/y/sample.txt
- This format has the accessKeyID and awsSecretKey specified in it.
@acts as the token to indicate the end of authentication information.
If you have specified the accessKeyID and awsSecretKey in both the URL and Application.cfc, then value specified in the URL takes precedence.
Example
<cffile action="write" output="S3 Specifications" file="s3://accessKeyID:awsSecretKey@bucket/x/y/sample.txt"/>
Enhancements to Amazon S3 integration
Apart from performance improvements while uploading files to Amazon S3, ColdFusion 10 supports multipart upload where files are split into multiple parts and the parts are uploaded in parallel.
To configure multipart upload support, specify the following settings in the Application.cfc:
this.s3.minsizeformultipart=filesize _in_MB
The size you specify is treated as minimum, above which file upload is performed as multipart upload. This option is helpful when you have to upload files of huge sizes.
Supported operations
The following are the supported operations on Amazon S3:
- Create and delete bucket
- Get bucket location
- Read, write, copy, and delete object
- List keys in bucket
- Get and set metadata for object or bucket
- Get and set ACL for object or bucket
Bucket operations
Use the cfdirectory tag or the directory functions to perform the bucket operation (create, delete, or list).
|
Tag used |
Function |
Example |
---|---|---|---|
Create |
cfdirectory action="create" |
DirectoryCreate |
<cfdirectory action="create" directory="s3://bucket1"/> |
List keys |
cfdirectory action="list" |
DirectoryList |
<cfdirectory action="list" directory="s3://bucket1/X/y" /> Since Amazon S3 does not have the concept of directory , it returns the key name (that is, the full path) of objects contained in the bucket. Directory attribute in this case takes the path, for example, s3://bucket1 in which objects have to be searched. The path that follows the bucket name is used as a prefix to perform the list operation and all the objects that match the prefix are returned. In this case, the following attributes are ignored: recurse, type, and sort. |
Delete |
cfdirectory action="delete" |
DirectoryDelete |
<cfdirectory action="delete" directory="s3://bucket1"/> |
To verify if the bucket exists and is accessible, use the function directoryExists.
Object operations
All object operations are similar to file operations (read, write, copy, and delete). Therefore, the tag cffile and the file functions can be used to perform the operations. The following table describes the common scenarios:
Operation |
Tag used |
Function |
Example |
---|---|---|---|
Read |
cffile action="read" |
FileRead |
<cffile action="read" file="s3://testbucket/test.txt" variable="data"/> |
Write |
cffile action="write" |
FileWrite |
<cffile action="write" output="#data#" file="s3://testbucket/test.txt"/> |
Delete |
cffile action="delete" |
FileDelete |
<cffile action="delete" file="s3://testbucket/test.txt"/> |
Copy |
cffile action="copy" |
FileCopy |
<cffile action="copy" source="s3://testbucket/test.txt" destination="s3://bucket2/a/b.txt"/> |
The following are the supported functions:
- FileIsEOF
- FileReadBinary
- Filecopy
- FileReadLine
- FileExists
- FileWriteln
- FileOpen
- FileClose
- FileRead
- FileDelete
New attributes in cfdirectory action="create" tag
Attribute Added |
Description |
Example |
---|---|---|
storeLocation |
Used to change the location of the created bucket. The location can either be EU or US. The default location is US . |
<cfdirectory action="create" directory="s3://<bucketname>" storelocation="US"> |
storeACL |
An array of struct where each struct represents a permission or grant as discussed in aclObject. |
<cfdirectory action="create" directory="s3://<bucketname>" storeACL="aclObject"> |
Setting up access control
Amazon S3 lets you set access control list (ACL) for buckets and objects. The ACLs for buckets and objects are independent. You have to manage them separately. Also, object ACLs do not inherit from the bucket ACLs.
ACL consists of multiple Grants where each grant has a grantee and a permission. S3 allows three types of grantees:
- group
- canonical (ID)
The following are the possible permissions:
- read
- write
- read_acp
- write_acp
- full_control
See Amazon S3 ACL Documentation for more details.
ACLObject
ACLObject is an array of struct where each struct represents an ACL grant. The grantee details are as follows:
- group Must have the keys Group (with value all, authenticated, or log_delivery) and permission.
- email Must have the keys email and permission.
- canonical Must have the keys Id and permission. displayName is optional.
Sample ACLObject
owner_full = {email="xxx@yyy.com", permission="full_control"}; aclObj = [owner_full, all_read];
Access control functions
storeSetACL
Description
Sets the ACL for object or bucket.
Returns
Nothing
Syntax
StoreSetACL(url, ACLObject)
Parameters
Parameter |
Description |
---|---|
url |
Amazon S3 URLs (content or object) |
ACLObject |
An array of struct where each struct represents a permission or grant as discussed in ACLObject . |
History
ColdFusion 9 Update 1: Added this function
Usage
Use this function to set full permission. The function overwrites all existing permissions. Only the ones you set in the current context exist.
Example
<cfset dir = "s3://bucket_name"> <cfif !directoryExists(dir)> <cfset directorycreate(dir)> </cfif> <cfset perm = structnew()> <cfset perm.group = "all"> <cfset perm.permission = "read"> <cfset perm1 = structnew()> <cfset perm1.email = "email ID"> <cfset perm1.permission = "FULL_CONTROL"> <cfset myarrray = arrayNew(1)> <cfset myarrray = [perm,perm1]> <cfset fileWrite("#dir#/test.txt","This is to test all users permission")> <cfset StoreSetACL("#dir#/textl.txt","#myarrray#")> <cfset test = StoreGetACL ("#dirkey#/test.txt") > <cfdump var= "test"> <cfcatch> <cfdump var="#cfcatch#"> </cfcatch> </cftry>
storeAddACL
Description
Adds ACL to existing ACL for object or bucket.
Returns
Nothing
Syntax
StoreAddACL(url, ACLObject)
Parameters
Parameter |
Description |
---|---|
url |
Amazon S3 URLs (content or object). |
ACLObject |
An array of struct where each struct represents a permission or grant as discussed in ACLObject . |
History
ColdFusion 9 Update 1: Added this function
Usage
Use this function to add permissions to the existing ones.
Example
<cfset dir = "s3://bucket_name/"> <cfset perm = structnew()> <cfset perm.group = "authenticated"> <cfset perm.permission = "READ"> <cfset perm1 = structnew()> <cfset perm1.email = "email_ID"> <cfset perm1.permission = "READ_ACP"> <cfset myarrray = [perm,perm1]> <cfif NOT DirectoryExists(dir)> <cfset directoryCreate(dir)> </cfif> <cfset fileWrite("#dir#/Sample.txt","This is to test StoreAddACL")> <cfset StoreAddACL("#dir#","#myarrray#")> <cfset test = StoreGetACL(dirkey)> <cfdump var="#test#"> <cfcatch> <cfdump var="#cfcatch#"> </cfcatch> </cftry>
storeGetACL
Description
Gets the ACL object or bucket.
Returns
Returns an ACLObject
Syntax
StoreGetACL(url)
Parameters
Parameter |
Description |
---|---|
url |
Amazon S3 URLs (content or object) |
History
ColdFusion 9 Update 1: Added this function
Example
<cfset dir = "s3://bucket_Name"> <cfif NOT DirectoryExists(dir)> <cfset directoryCreate(dir)> </cfif> <cfset test = StoreGetACL("#dir#")> <cfdump var="#test#">
Using metadata
Amazon S3 allows you to specify metadata for both objects and buckets.
The following two functions let you get and set the metadata on objects or buckets.
StoreGetMetadata
Description
Returns the metadata related to the object or bucket.
Returns
Object metadata or bucket metadata
Syntax
StoreGetMetadata(url)
Parameters
Parameter |
Description |
---|---|
url |
Amazon S3 URLs (bucket or object). |
History
ColdFusion 9 Update 1: Added this function
Example
<cfdump var = #StoreGetMetadata("bucket_Name")#>
StoreSetMetadata
Description
Sets the metadata on bucket or object.
Returns
Nothing
Syntax
StoreSetMetadata(url,Struct)
Parameters
Parameter |
Description |
---|---|
url |
Amazon S3 URLs (bucket or object). |
struct |
Represents the metadata. See Standard keys (in this page) for a list of standard keys in metadata.You can also have custom metadata apart from the standard ones. |
History
ColdFusion 9 Update 1: Added this function
Example
mydate = #Now()#; hello = structNew(); hello.color = "grey"; /cfscript> <cfset dir = "s3://mycfbucket"> <cffile action="write" file="#dir#/hello5.txt" output="Sample s3 text"> <cfset StoreSetMetadata("#dir#/hello5.txt","#hello#")> <cfset test = StoreGetMetadata("#dir#/hello5.txt")> <cfdump var="#test#">
Standard keys
The following are the standard keys in the metadata:
For objects
- last_modified
- date
- owner
- etag
- content_length
- content_type
- content_encoding
- content_disposition
- content_language
- content_md5
- md5_hash
For buckets
- date
- owner
Security considerations
Sandboxing is not applicable to S3 buckets or objects as Amazon S3 has its own security features that take care of it.
Supported functions
fileOpen |
fileClose |
fileCopy |
fileDelete |
---|---|---|---|
fileExists |
fileisEOF |
fileMove |
fileWrite |
fileRead |
fileReadBinary |
fileReadLine |
fileSetLastModified |
getFileInfo |
getDirectoryFromPath |
directoryCreate |
directoryDelete |
directoryExists |
directoryList |
imageNew |
imageRead |
imageWrite |
imageWriteBase64 |
isImageFile |
isPDFFile |
Supported tags
All cffile actions |
All cfdirectory actions (except rename) |
cfdocument |
cffeed |
---|---|---|---|
cfftp |
cfimage |
cfloop |
All cfimage actions |
Enhancements in ColdFusion 10
Apart from performance improvements while uploading files to Amazon S3, ColdFusion 10 supports multipart upload where files are split into multiple parts and the parts are uploaded in parallel.
To configure multipart upload support, specify the following settings in the Application.cfc:
this.s3.minsizeformultipart=filesize _in_MB
The size you specify is treated as minimum , above which file upload is performed as multipart upload. This option is helpful when you have to upload files of huge sizes.
Limitations
- The following tags are not supported:
- cfpdf
- cfpdfform
- The following functions are not supported:
- FileSetAccessMode that sets attributes of a file in Linux/UNIX
- FilesSetAttribute that sets the attributes of a file in Windows
- cfzip does not accept Amazon S3 object as source.
- When S3 object is used as output for outputfile attribute of cfexecute tag, it results in an error Timeout period expired without completion of <exe>. It also results in a NullPointerException at server console.
- To use the function fileMove , the source and destination objects must have the same bucket name. That is, you cannot move Amazon S3 objects across buckets or to other file systems.
Working with in-memory files
Memory-based virtual file system speeds up the processing of transient data. In-memory files are not written to disk and are saved on RAM. They function similar to disk files but perform faster.
In ColdFusion, in-memory files help you to simplify the execution of dynamic code. In-memory files are supported across almost all tags and functions that take file or directory as input or output.
You use in-memory files in the same manner as files on disk, but with a prefix ram:/// to indicate that they reside on RAM. For example, ram:///a/b/dynamic.cfm.
Writing and executing dynamic CFM files
The following syntax explains how to write CFM data in to an in-memory file:
file="ram:///filename.cfm"/>
The following sample syntax explains how to use the in-memory CFM file:
For tags that take logical path, define mapping in Administrator. Execute in-memory CFM pages using the cfincludetag :
<cfinclude template="/inmemory/filename.cfm">
Create a mapping for ram:/// so that it can be used in the tags. In this example, / inmemory is the mapping that points to ram:///.
For tags that take absolute path, specify the syntax as provided in the following example:
<cffile action="append" file="ram:///a/b/dynamic.cfm" output="I'm appending">
You cannot have Application.cfm as an in-memory file. If you have one, it is ignored.
Example
The following code describes how to write an image as an in-memory file:
<cffile action="readBinary" variable="myImage" file="#ExpandPath('./')#/blue.jpg"> <cffile action="write" output="#myImage#" file="ram:///a.jpg"> <cfif FileExists("ram:///a.jpg")> <cfoutput>a.jpg exists</cfoutput> <cfelse> <cfoutput>a.jpg Doesn't exists</cfoutput> </cfif>
Writing and instantiating dynamic CFC files
The following syntax explains how you can write CFC code in to an in-memory file:
file="ram:///filename.cfc"/>
The following sample syntax explains how you can instantiate the in-memory CFC file:
<cfset cfc=CreateObject("component","inmemory.filename")/>
Here, inmemory is the ColdFusion mapping that points to ram:///.
You cannot have Application.cfc as an in-memory file. If you have one, it is ignored.
Example
The following code writes a CFC as in-memory file:
<cffile action="read" file="#ExpandPath('./')#/dynamic.cfc" variable="Message"> <cffile action="write" file="ram:///cfc/dynamic.cfc" output="#Message#">
To invoke a component method:
<cfinvokeargument name="paramOne" value="hello"> </cfinvoke> <cfoutput>#returnVariable#</cfoutput>
Working with in-memory file system
The following sections provide information that can help you to access and use in-memory files.
Using in-memory files
- You can call a CFC saved on RAM from a CFM file on disk. Similarly, an in-memory CFM file can call a CFC saved on disk.
If a CFC extends another CFC in the same directory in RAM, you can use relative path. For instance, if a.cfc and b.cfc belong to the same directory in RAM, a.cfc can extend b.cfc using relative path as shown in the following code:
</cfcomponent>
- You can use in-memory ColdFusion interfaces in the same way as you use in-memory CFCs.
Supported functions
The following file functions are supported for in-memory files:
- FileIsEOF
- FileReadBinary
- Filemove
- Filecopy
- FileReadLine
- FileExists
- FileOpen
- FileWriteln
- FileClose
- FileRead
- FileDelete
- DirectoryExists
- FileSetLastModified
- GetFileInfo
- GetDirectoryFromPath
- GetFileFromPath
- ImageNew
- ImageRead
- ImageWrite
- ImageWriteBase64
- IsImageFile
- IsPDFFile
- FileSetLastModified
Example
The following syntax explains the function FileSetLastModified()
<cffile action="write" file="ram:///a.txt" output="Testing the function FileSetLastModified"> <cfset date="12/12/2007"> <cfscript> FileSetLastModified("ram:///a.txt", "#date#"); sleep(1000); WriteOutput(#GetFileInfo("ram:///a.txt").lastmodified#); </cfscript> <cfcatch> <cfset PrintException(cfcatch)> </cfcatch> </cftry> <cf_expectedresults>{ts '2007-12-12 00:00:00'} </cf_expectedresults>
File operations
The following file operations are supported for in-memory files:
- Directory-specific operations: create, delete, list, and rename.
- File-specific operations: copy, create, write, append, delete, rename, create attributes, modes move, and read.
Example
The following code illustrates the file and directory operations:
<cfdirectory action = "create" directory = "ram://src" > <cfdirectory action = "create" directory = "ram://des" > <cfdirectory action = "rename" directory = "ram:///CurrentDir" newDirectory = "NewDir"> <cfdirectory action="list" directory="ram://" name="listDir" recurse="yes" > <cfdump var="#listDir#"> <cffile action="write" file = "ram://src/test.txt" output = "Release Description"> <cffile action="copy" source="ram://src/test.txt" destination="ram://des/final.txt" > <cffile action="rename" source = "ram:///src/message.txt" destination = "ram:///des/test.txt"> <cffile action ="move" source = "ram:///des/test.txt" destination = "c:\des\move.txt">
Document and image actions
All image and document actions can use in-memory image files as shown in the following examples:
<cfimage action="captcha" fontSize="15" width="180" height="50" text="readMe" destination="ram:///readMe.jpg" difficulty="medium"> <cfimage source="ram://aiden02.png" action="convert" destination="#ExpandPath("./")#/blue1.JPG" overwrite="yes"> <cfdocument format="pdf" filename="ram://Sample.pdf" overwrite="yes">Sample Text</cfdocument>
Custom tags
In-memory CFM pages and CFCs can call custom tags but the custom tags must be present in disk. In-memory custom tags are not supported.
Using in-memory files in tags
The following tags are supported for in-memory files:
- cfcontent
- cfdocument
- cfdump
- cfexchange
- cfexecute
- cffeed
- cfhttp
- cfftp
- cfimage
- cfloop
- cfpresentation
- cfprint
- cfreport
- cfzip
Example using the tag cfcontent
<cfcontent file="ram:///a.jpg" type="image/jpeg" deletefile="yes">
Adding permissions
ColdFusion lets you add permissions for directories/files on RAM using an existing sandbox security setup. You can only set up sandbox security for disk directories and not for RAM directories. Access to an in-memory directory/file can be restricted only through an existing local file system sandbox.
Therefore, to set up sandbox security for in-memory files, select a sandbox that you have already configured for a disk directory.
By default the ram:/// directories are included in the list of secured folders and have read, write, execute, and delete permissions set. Therefore, all RAM files have permissions by default in a sandbox. All the security restrictions that apply to disk files apply to in-memory files.
To set up Sandbox security for in-memory files,
-
Open the Security > Sandbox Security page in the ColdFusion Administrator.The Sandbox Security Permissions page appears.
-
In the Add Security Sandbox box, specify a disk directory and then click Add.
-
In Files/Directories, specify the in-memory file path. For example, ram:///a/b (for directory) or ram:///a/b/dynamic.cfm (for file).
-
Select the required permissions, click Add Files/Paths, and then click Finish.
For further details on sandbox security, refer to the ColdFusion Administration Guide.
Accessing VFS information
The GetVFSMetaData function lets you access VFS information. This function takes the parameter RAM as input.
This function returns a structure that contains the following information:
- If support for in-memory virtual file system is enabled
- Memory limit in bytes for in-memory virtual file system
- The used and free memory
For example, <cfdump var="#getVFSMetaData("ram")#">
The Settings page of the ColdFusion Administrator has the options to enable/disable the in-memory virtual file system support. You can also specify the memory limit in Megabytes (MB) for in-memory virtual file system.
Deleteing in-memory files
The in-memory files remain in RAM as long as the server is up. When required, clean up the files using cffile/cfdirectory with the action=delete. For example, delete all the contents in RAM directory "ram://a/b" using the following code: <cfdirectory action="delete" directory="ram:///a/b" recurse="yes">
Limitations
- File names/Directory names on RAM are case sensitive.
- In-memory files must be accessed using mapping or absolute path. Relative paths to files/directories are not supported.
- Correct: ram:///a/b/
- Incorrect: ram:///a/b/../..
- You cannot access in-memory files using HTTP/HTTPS protocols. Instead, use ram:///<file>. For example, ram:///a/b/test.cfm.
- DDX files and font files cannot be accessed as in-memory files.
- The following functions are not supported for in-memory files.
- FileSetAccessMode that sets attributes of a file in Linux/Unix
- FilesSetAttribute that sets the attributes of a file in Windows
- The following tags are not supported:
- cfpdf
- cfpdfform
- The following scenarios are not supported:
The cfreporttag does not accept a template report on RAM. Therefore, the following does not work:
<cfreport format="PDF" template="ram:///myReport1.cfr" filename="ram:///test.pdf" overwrite="yes">
In this case, the myReport1.cfr must reside on your disk.
- The cfimporttag does not accept tag libraries on RAM. For instance, the following does not work:
<cfimport prefix="custom" taglib="ram:///a/b/mytags.jar">
- Renaming across file systems (as shown in the following syntax) is not supported.
<cffile action="rename" source="ram:///src1/message2.txt" destination="#ExpandPath('./')#/123.txt">.
Instead, you can move the files.
- For the cfexecutetag , the executable cannot be on RAM and must be on your local file system. But the output can be an in-memory file as illustrated in the following code:
<cfexecute name="C:\WINDOWS\System32\netstat.exe" arguments="-e" outputFile="ram:///output.txt" timeout="1"> </cfexecute> <cfset thisPath=ExpandPath("*.*")>
Application-specific In-memory file system
ColdFusion 9 supports in-memory file system only at server level. But the enhancements in this release let you use in-memory file system specific to applications. This enables application isolation for your virtual file system. That is, the file created in the in-memory file system by one application is not accessible to another application.
The settings can be specified in the Application.cfc as follows:
Variable |
Description |
---|---|
this.inmemoryfilesystem.enabled |
Set the value to true to enable in-memory file system for application . This is the default setting. |
this.inmemoryfilesystem.size |
Specify the memory limit in MB for the in-memory file system.You can also specify the value in the ColdFusion Administrator (Server Settings > Settings > Memory Limit per Application for In-Memory Virtual File System).The lesser value is considered. |
Virtual File System: Support for HTTP, FTP, and ZIP
ColdFusion 10 lets you access files over network through FTP or HTTP protocol. Also provided is support for ZIP.
For conventions, see the Apache Commons Documentation.
Examples
For FTP:
action = "read" file = "ftp://Administrator:Password@Host_Name/ReadmeLater.htm" variable = "varvar"> <cffile action="write" file="ftp://Administrator:Password@Host_Name/ReadmeLater.htm" output="new stuff added">
For ZIP
action = "read" file="zip:#ExpandPath('./')#/hello.zip!/hello.txt" variable = "varRead1">
Optimizing database use
Poor database design and incorrect or inefficient use of the database are among the most common causes of inefficient applications. Consider the different methods that are available for using databases and information from databases when you design your application. For example, to average the price of many products from a SQL query, it is more efficient to use SQL to get the average than to use a loop in ColdFusion.
Two important ColdFusion tools for optimizing your use of databases are the cfstoredproc tag and the cfquery tag cachedWithin attribute.
Using stored procedures
The cfstoredproc tag lets ColdFusion use stored procedures in your database management system. A stored procedure is a sequence of SQL statements that is assigned a name, compiled, and stored in the database system. Stored procedures encapsulate programming logic in SQL statements, and database systems are optimized to execute stored procedures efficiently. As a result, stored procedures are faster than cfquery tags.
You use the cfprocparam tag to send parameters to the stored procedure, and the cfprocresult tag to get the record sets that the stored procedure returns.
The following example executes a Sybase stored procedure that returns three result sets, two of which the example uses. The stored procedure returns the status code and one output parameter, which the example displays.
<cfstoredproc procedure = "foo_proc" dataSource = "MY_SYBASE_TEST" username = "sa" password = "" returnCode = "Yes"> <!--- cfprocresult tags ---> <cfprocresult name = RS1> <cfprocresult name = RS3 resultSet = 3> <!--- cfprocparam tags ---> <cfprocparam type = "IN" CFSQLType = CF_SQL_INTEGER value = "1"> <cfprocparam type = "OUT" CFSQLType = CF_SQL_DATE variable = FOO> <!--- Close the cfstoredproc tag. ---> </cfstoredproc> <cfoutput> The output param value: '#foo#'<br> </cfoutput> <h3>The Results Information</h3> <cfoutput query = RS1> #name#,#DATE_COL#<br> </cfoutput> <br> <cfoutput> <hr> Record Count: #RS1.recordCount#<br> Columns: #RS1.columnList#<br> <hr> </cfoutput> <cfoutput query = RS3> #col1#,#col2#,#col3#<br> </cfoutput> <br> <cfoutput> <hr><br> Record Count: #RS3.recordCount#<br> Columns: #RS3.columnList#<br> <hr> The return code for the stored procedure is: '#cfstoredproc.statusCode#'<br> </cfoutput>
Reviewing the code
The following table describes the code and its function:
Code |
Description |
---|---|
<cfstoredproc procedure = "foo_proc" dataSource = "MY_SYBASE_TEST" username = "sa" password = "" returnCode = "Yes"> |
Runs the stored procedure foo_proc on the MY_SYBASE_TEST data source. Populates the cfstoredproc statusCode variable with the status code returned by stored procedure. |
<cfprocresult name = RS3 resultSet = 3> |
Gets two record sets from the stored procedure: the first and third result sets it returns. |
<!--- Close the cfstoredproc tag. ---> |
Specifies two parameters for the stored procedure, an input parameter and an output parameter. Sets the input parameter to 1 and the ColdFusion variable that gets the output to FOO.Ends the cfstoredproc tag body. |
</cfoutput> |
Displays the results of running the stored procedure:
|
For more information on creating stored procedures, see your database management software documentation. For more information on using the cfstoredproc tag, see the CFML Reference.
Using the cfquery tag cachedWithin attribute
The cfquery tag cachedWithin attribute tells ColdFusion to save the results of a database query for a specific period of time. This way, ColdFusion accesses the database on the first page request, and does not query the database on further requests until the specified time expires. Using the cachedWithin attribute significantly limits the overhead of accessing databases that do not change rapidly.
This technique is useful if the database contents only change at specific, known times, or if the database does not change frequently and the purpose of the query does not require up- to-date results.
Use the CreateTimeSpan function to specify the cachedWithin attribute value (in days, hours, minutes, seconds format). For example, the following code caches the results of getting the contents of the Employees table of the cfdocexamples data source for one hour.
cachedWithin="#CreateTimeSpan(0,1,0,0)#"> SELECT * FROM Employees </cfquery>
Optimizing transient files
Providing visual feedback to the user
If an application takes a while to process data, it is useful to provide visual feedback to indicate that something is happening, so the user does not assume that there is a problem and requests the page again. Although doing this does not optimize your application's processing efficiency, it does make the application appear more responsive.
Use the cfflush tag to return partial data to a user, as shown in Introduction to Retrieving and Formatting Data.
You can also use the cfflush tag to create a progress bar.