DevLearningTools

MODULE 11 · LESSON 01

cffile (Reading & Writing Files)

Reading, writing, and appending to files with <cffile> and its CFScript function equivalents (fileRead, fileWrite, fileAppend), plus reading a large file efficiently line by line with fileOpen.

New lessons are added one at a time as the course gets built out — a graded quiz for each lesson is still on the way.

<cffile> is CFML's core tag for file operations: reading a file's contents, writing or appending text to one, and (covered in the next lesson) handling an uploaded file. Modern CFScript code more often reaches for the equivalent built-in functions, fileRead(), fileWrite(), and fileAppend(), which do the same job without the tag syntax.

Learning Objectives

After completing this lesson, you'll be able to:

  • Read, write, and append to a text file using both cffile and its CFScript function equivalents.
  • Read a large file efficiently, line by line, instead of loading it entirely into memory.
  • Know the real security gotcha with cffile: it performs no validation on its own.

How cffile Fits In

Your Code

cffile / fileRead / fileWrite

File on Disk

NOTE

Every action, read, write, or append, is really the same round trip: your code asks cffile (or its CFScript function equivalent) to talk to a real file sitting on disk, and gets the result (or confirmation) back.

Reading a File

Tag Syntax
<cffile action="read" file="#expandPath('./message.txt')#" variable="message">
<cfoutput>#message#</cfoutput>
CFScript
message = fileRead(expandPath("./message.txt"));
writeOutput(message);

Writing a File

Tag Syntax
<cffile action="write" file="#expandPath('./log.txt')#" output="Created by: #form.name#">
CFScript
fileWrite(expandPath("./log.txt"), "Created by: " & form.name);
NOTE

action="write" (and fileWrite()) overwrites the file completely if it already exists. For adding to an existing file without erasing it, use append instead.

Appending to a File

Tag Syntax
<cffile action="append" file="#expandPath('./log.txt')#" output="Appended by: #form.name#">
CFScript
fileAppend(expandPath("./log.txt"), "Appended by: " & form.name);

The cffile Action Attribute: Full Reference

actionWhat it does
readReads a text file's full contents into a variable
readbinaryReads a binary file's contents (images, PDFs) into a variable
writeCreates a file, overwriting it if it already exists
appendAdds content to the end of an existing file
uploadProcesses an uploaded file from a form submission (next lesson)
copyCopies a file to a new location
move / renameMoves or renames a file
deleteDeletes a file
info (Lucee only)Retrieves file metadata, size, dates, without reading its contents
touch (Lucee only)Creates an empty file, or updates an existing file's timestamp
NOTE

info and touch aren't part of Adobe ColdFusion's cffile at all, they're Lucee-specific additions. Confirm both engines support whatever action is actually needed before relying on either.

Lucee-Specific Extensions Worth Knowing

AttributeWhat it adds
cachedWithinCaches a read/readbinary result (a timespan, or "request" scope), avoiding re-reading the same file repeatedly
allowedExtensions / blockedExtensionsRestricts which file extensions an upload can accept or must reject, built directly into the tag (Lucee 5.3.8.107+)
createPathAutomatically creates the destination directory for write, append, or touch if it doesn't already exist
NOTE

allowedExtensions and blockedExtensions matter specifically for the earlier security gotcha, on Lucee, they're a real, built-in way to restrict what cffile will accept, not something the developer has to reimplement entirely from scratch. Adobe ColdFusion instead relies on the accept and strict attributes on the upload action specifically, covered in the next lesson.

Reading a Large File Efficiently

fileRead() loads the entire file into memory at once, fine for a small config or log file, but wasteful for a genuinely large file. fileOpen() combined with fileReadLine() processes a file one line at a time instead.

fileOpen()

fileReadLine()

one line at a time

fileIsEOF()?

loop until true

fileClose()

CFScript
fileObj = fileOpen(expandPath("./large-log.txt"), "read");

while (!fileIsEOF(fileObj)) {
    line = fileReadLine(fileObj);
    // process this one line
}

fileClose(fileObj);
NOTE

fileIsEOF() checks whether the end of the file has been reached, and the loop keeps going until it has. Always close the file with fileClose() when done, an open file handle left dangling can lock the file or leak resources.

A Real Gotcha: cffile Performs No Validation on Its Own

That's Adobe's own documentation, stated plainly. cffile does exactly what it's told, writing to whatever path it's given, reading whatever file exists there. Nothing about the tag itself stops a path built from unvalidated user input from writing somewhere it shouldn't, or reading a file it has no business exposing.

This example performs no error checking and does not incorporate any security measures. Before deploying an application that performs file uploads, ensure that you incorporate both error handling and security.

Common Beginner Mistakes

Using action="write" when the intent was to add to an existing file

write overwrites the file completely. Use append to add content without erasing what's already there.

Building a file path directly from user input with no validation

cffile performs no security checks on its own, per Adobe's own documentation. A path built from unvalidated input can read or write files far outside where the application intended.

Loading a genuinely large file with fileRead() instead of reading it line by line

fileRead() pulls the entire file into memory at once. For a large file, fileOpen() with fileReadLine() in a loop processes it incrementally instead.

Forgetting to close a file opened with fileOpen()

An open file handle left open with fileClose() never called can lock the file for other processes or leak resources over time.

Best Practices

  • Validate and constrain any user-influenced path before passing it to cffile, never trust it directly.
  • Use fileWrite/fileRead (or their tag equivalents) for small files, and fileOpen with fileReadLine for large ones.
  • Always pair fileOpen() with a matching fileClose(), ideally inside a try/finally so it closes even if an error occurs mid-read.
  • Prefer the CFScript functions (fileRead, fileWrite, fileAppend, fileOpen) in new CFScript-based code; the cffile tag remains fully supported but reads more naturally in Tag Syntax files.

Interview Questions

What's the difference between cffile action="write" and action="append"?

write creates the file, overwriting it entirely if it already exists. append adds content to the end of an existing file without erasing what's already there.

What's the CFScript equivalent of <cffile action="read">?

fileRead(path), which returns the file's contents directly as a string.

Why would you use fileOpen() and fileReadLine() instead of fileRead()?

fileRead() loads the entire file into memory in one call, which doesn't scale well for a genuinely large file. fileOpen() with fileReadLine() in a loop processes the file one line at a time instead.

Does cffile validate or restrict what paths it can read from or write to?

No. Adobe's own documentation states cffile performs no error checking or security measures on its own, validating any user-influenced path is the application's responsibility.

Name a cffile action that exists on Lucee but not on Adobe ColdFusion.

info (retrieves file metadata without reading its contents) and touch (creates an empty file or updates its timestamp) are both Lucee-specific, neither is part of Adobe ColdFusion's cffile.

Summary

In this lesson, you read, wrote, and appended to files using both cffile and its CFScript function equivalents (fileRead, fileWrite, fileAppend), read a large file efficiently line by line with fileOpen/fileReadLine/fileIsEOF, and covered the real gotcha that cffile performs no validation on its own.

What's Next?

The next lesson covers uploading files specifically, cffile's upload action, handling a form submission's file field, and the real security considerations around accepting a file from a user.