CodFusion 8 adds three new attributes (characters, file, and array) to the CFloop tag that make it a little easier to loop through the contents of files and arrays. The array attribute is pretty cool, but the file/characters attributes are really exciting for me. In previous versions of ColdFusion, to loop through an array you would create the loop to basically count from 1 to the length of the array, then access each item in the array within the loop like:

<cfloop from="1" to="#ArrayLen(myArray)#" index="i">
#myArray[i]#<br>
</cfloop>

ColdFusion 8 makes array looping a little simpler, you can specify the array attribute and the index variable will hold the contents of each array item.

<cfloop array="#myArray#" index="i">
#i#<br>
</cfloop>

Looping through the contents of a text file is something I have done often, particularly when developing data integration processes between my ColdFusion applications and other systems. For example, if you were importing records from a CSV file in to a table, to loop through the lines of a file you used to have to read the file and convert the lines to an array, then loop through the array of lines, like this:

<!--- read the file --->
<cffile action="READ" file="c:myDirmyFile.csv" variable="MyFile">

<!--- Convert the lines to an array using the carriage return/line feed characters as delimiters --->
<cfset FileLines = listtoarray(MyFile,"#chr(13)##chr(10)#")>

<!--- Loop through the array of lines --->
<cfloop from="1" to="#arrayLen(FileLines)#" index="i">
   <!--- do your processing for each of the lines --->
   <cfquery name="InsertRecord" datasource="MyDSN">
   INSERT INTO MyTable (Field1,Field2,Field3)
      VALUES ('#listgetat(FileLines[i],1)#','#listgetat(FileLines[i],2)#','#listgetat(FileLines[i],3)#')
   </cfquery>
</cfloop>

Now you can do the same thing by just pointing the cfloop to the file like this:

<!--- Loop through the lines of the file --->
<cfloop file="c:myDirmyFile.csv" index="FileLine">
   <!--- do your processing for each of the lines --->
   <cfquery name="InsertRecord" datasource="MyDSN">
   INSERT INTO MyTable (Field1,Field2,Field3)
      VALUES ('#listgetat(FileLine,1)#','#listgetat(FileLine,2)#','#listgetat(FileLine,3)#')
   </cfquery>
</cfloop>

If you are importing data from a file with fixed field lengths that doesn't use line feeds or carriage returns, you can use the "characters" attribute to tell the CFloop when how long each record is and it will us that instead of reading each line. For example if each record in your file consists of 30 characters, then you could loop through the records like this:

<!--- Loop through the records in the file --->
<cfloop file="c:myDirmyFile.txt" characters="30" index="FileRecord">
   <!--- do your processing for each of the records--->
   <cfquery name="InsertRecord" datasource="MyDSN">
   INSERT INTO MyTable (Field1,Field2,Field3)
      VALUES ('#trim(left(FileLine,10))#','#trim(mid(FileLine,11,10))#','#trim(right(FileLine,10))#')
   </cfquery>
</cfloop>

Overall, I think the new ability to loop through the contents of a file in ColdFusion 8 is pretty slick, and I wish they would have done this sooner. I can't even tell you how many times I have seen the "how do I loop through a files lines?" question asked on various ColdFusion forums.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Chris Peters's Gravatar Thanks for the great overview. I didn't know this was available until today!

I know, nit-picky, but in your last example, shouldn't index="FileRecord" be index="FileLine"?
# Posted By Chris Peters | 1/16/08 3:04 PM
Scott Bennett's Gravatar Yes it should, good catch. As you can see, typical overconfident programmer that I am, I didn't test that code, I just wrote it into the article.
# Posted By Scott Bennett | 1/16/08 3:35 PM
Chris Peters's Gravatar I do the same thing when I post code. :)
# Posted By Chris Peters | 1/16/08 3:37 PM
mgwalk's Gravatar I like how you use the cfloop file part! I love finding new ways to read through files!

Thanks
# Posted By mgwalk | 3/7/08 4:46 PM
Zachary M. Williams's Gravatar Interesting approach. I like it.
# Posted By Zachary M. Williams | 5/29/09 5:45 PM