ColdFusion Quickie - Moving a file to a day-based folder

This post is more than 2 years old.

Here is a quick ColdFusion tip I hope people find useful. Let's say you have a site where users upload files. You may store all these files in one main assets folder. Doing so though could lead to a very large folder, and after time could actually impact performance. What about creating dynamic folders based on the date? So if a user uploads a file today, it would be moved to assetroot/2009/6/10. Here is a quick example of that.

First, our code needs to determine what the folder name for the current date should be. Normally I would begin with an "assets" folder, but for this example, I'll consider the root folder to be the same folder as the CFM:

<cfset folder = getDirectoryFromPath(getCurrentTemplatePath())>

To create the date based folder, I'll use the format described above - year/month/day.

<cfset newFolder = folder & "/" & year(now()) & "/" & month(now()) & "/" & day(now())>

Remember from my Cross Operating System Guide that the forward slash works perfectly across all operating systems. No need to worry about \ versus /.

Now we need to see if this folder already exists. If multiple people are uploading files, you only need to create the folder once:

<cfif not directoryExists(newFolder)> <cfdirectory action="create" directory="#newFolder#"> </cfif>

What's nice is - even if the year folder, or month folder, doesn't exist, ColdFusion will create them for you. If the year and month folders exist, ColdFusion will just create the day folder.

Finally, you just need to move the file. If you were using cffile to process the upload, you could use the destination attribute. In my sample code, I just used a hard coded file.

<cfset fileToMove = expandPath("./missing.jpg")>

<cfset fileMove(fileToMove,newFolder & "/" & getFileFromPath(fileToMove))>

I pointed to a file in the same folder, missing.jpg, and used the fileMove function. Note how I get the file from the complete source path and use the newFolder attribute.

Here is the complete template (with a few additional outputs for testing):

<cfset folder = getDirectoryFromPath(getCurrentTemplatePath())>

<cfset newFolder = folder & "/" & year(now()) & "/" & month(now()) & "/p" & day(now())> <cfoutput>new folder is #newFolder#<br/></cfoutput>

<cfif not directoryExists(newFolder)> nope, doesn't exist<br/> <cfdirectory action="create" directory="#newFolder#"> </cfif>

<cfset fileToMove = expandPath("./missing.jpg")>

<cfset fileMove(fileToMove,newFolder & "/" & getFileFromPath(fileToMove))>

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Nick posted on 6/10/2009 at 10:02 PM

This is a very slick tip. I've done something similar with images and categories (not just making folders by date). I guess I did not do the mental math to know that CF would handle the folder creation if 2 of the 3 parts already existed, but its one of those "of course it will" moments.

Comment 2 by Raymond Camden posted on 6/10/2009 at 10:05 PM

Nick - to be clear, I did NOT think it would. Maybe it didn't in CF7 or 6. I seem to remember having to 'walk the path', in fact, I was planning on it for the blog entry. If someone is on 7 or 6 and wants to test, I'd love to see it. And if you and I right that it changed, I'll do an example of that.

Comment 3 by Eric Cobb posted on 6/10/2009 at 11:00 PM

Wow! You're right. I just did a quick test on CF 8 where I created a directory with 3 other directories inside of it. I know for a fact that this didn't work before, because I've had to create a java object and use mkdirs() to get it to work in the past. But, at that time we were actually running CF 6, 7, and 8 servers so I don't remember which one it was....

Good find!

Comment 4 by Gary Funk posted on 6/10/2009 at 11:07 PM

CF7 will create the necessary directories.

Comment 5 by Raymond Camden posted on 6/10/2009 at 11:18 PM

Someone want to find a CF6 server and test? I think we can stop there and not worry about CF5. ;)

Comment 6 by Daniel Sellers posted on 6/10/2009 at 11:50 PM

Just tested on CF 6 and while the fileMove breaks it creates the file structure perfectly. Even if part of it has already been created.

Must have been 5 or 4 that had problems with walking directory structure...

Comment 7 by Raymond Camden posted on 6/10/2009 at 11:53 PM

Thanks for testing Daniel, Gary.

Comment 8 by sam Farmer posted on 6/11/2009 at 1:00 AM

This is like two ColdFusion Quickies in one entry:
- the slick example
- and finding out cfdirectory will create more than one directory


Comment 9 by Raymond Camden posted on 6/11/2009 at 1:10 AM

@sam: I am aim to please.

Comment 10 by dickbob posted on 6/11/2009 at 1:51 AM

Hey, why not use DateFormat(Now(),"yyyy/mm/dd") for the date part of the pathname?

Comment 11 by Raymond Camden posted on 6/11/2009 at 1:54 AM

Because that would be simpler. ;)

Comment 12 by Pragnesh Vaghela posted on 6/11/2009 at 9:07 PM

Posting this solution in case you have a ton of files to organize: