<?xml version="1.0" encoding="utf-8"?>

			<rss version="2.0" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cc="http://web.resource.org/cc/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">

			<channel>
			<title>StinkyLittleFriend</title>
			<link>http://www.stinkylittlefriend.com/blog/index.cfm</link>
			<description>A blog of sorts (not sure what sorts though).</description>
			<language>en-us</language>
			<pubDate>Mon, 21 May 2012 07:02:16 +0100</pubDate>
			<lastBuildDate>Tue, 13 Mar 2012 07:01:00 +0100</lastBuildDate>
			<generator>BlogCFC</generator>
			<docs>http://blogs.law.harvard.edu/tech/rss</docs>
			<managingEditor>glen@stinkylittlefriend.com</managingEditor>
			<webMaster>glen@stinkylittlefriend.com</webMaster>
			<itunes:subtitle></itunes:subtitle>
			<itunes:summary></itunes:summary>
			<itunes:category text="Technology" />
			<itunes:category text="Technology">
				<itunes:category text="Podcasting" />
			</itunes:category>
			<itunes:category text="Technology">
				<itunes:category text="Tech News" />
			</itunes:category>
			<itunes:keywords></itunes:keywords>
			<itunes:author></itunes:author>
			<itunes:owner>
				<itunes:email>glen@stinkylittlefriend.com</itunes:email>
				<itunes:name></itunes:name>
			</itunes:owner>
			
			<itunes:explicit>no</itunes:explicit>
			
			<item>
				<title>ColdFusion; extracting substrings and multibyte chars</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2012/3/13/ColdFusion-extracting-substrings-using-the-Mid-function-and-multibyte-chars</link>
				<description>
				
				We have a service that returns xml. The xml is not how you&apos;d expect i.e. where a parent node represents a record and the child nodes represent fields relevant to the current record. So to be clear, it isn&apos;t like this:

&lt;code&gt;
&lt;links&gt;
	&lt;linkData&gt;
		&lt;link&gt;mylinkhere&lt;/link&gt;
		&lt;linkText&gt;mylink text here&lt;/linkText&gt;
	&lt;/linkData&gt;
	&lt;linkData&gt;
		&lt;link&gt;myotherlinkhere&lt;/link&gt;
		&lt;linkText&gt;myotherlink text here&lt;/linkText&gt;
	&lt;/linkData&gt;
...etc
&lt;/links&gt;
&lt;/code&gt;

Instead it concatenates the contents of fields so it would concatenate the two &quot;link&quot; fields in one node and concatentate the two &quot;linkText&quot; nodes in another node. Then it would add a &quot;length&quot; node to show how long each entry would be - it ends up looking looking like this:

&lt;code&gt;
&lt;linkdata&gt;
	&lt;link&gt;
		&lt;length&gt;9,15&lt;/length&gt;
		&lt;text&gt;mylinkheremyotherlinkhere&lt;/text&gt;
	&lt;/link&gt;
	&lt;linkText&gt;
		&lt;length&gt;16,21&lt;/length&gt;
		&lt;text&gt;mylink text heremyotherlink text here&lt;/text&gt;
	&lt;/linkText&gt;
&lt;/linkdata&gt;
&lt;/code&gt;

I assumed the the length represented the character count and based on that assumption I had used the &lt;a href=&quot;http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7b56.html&quot;&gt;ColdFusion Mid() function&lt;/a&gt;.

It turns out the length actually represented the byte length, so if there were any multibyte characters then my mid function would extract too much.

Here is a code sample using the first technique (I have represented the xml as a struct):

&lt;code&gt;
&lt;cfprocessingdirective pageencoding=&quot;utf-8&quot;&gt;

&lt;cfset str = {}&gt;
&lt;cfset str[&quot;links&quot;] = {lengths=&quot;53,28,25&quot;,text=&quot;http://my.url.com/with multibyte chars _???.pdfhttp://my.url.com/normal.pdfhttp://my.url.com/?.pdf&quot;,colour=&quot;red&quot;}&gt;
&lt;cfset str[&quot;linkText&quot;] = {lengths=&quot;54,22,22&quot;,text=&quot;A link to my first multibyte url look it has ???A link to a normal urlOne more link with ?&quot;,colour=&quot;blue&quot;}&gt;

&lt;cfdump var=&quot;#str#&quot;&gt;

&lt;cfset numberOfRecords = 3&gt;

&lt;!--- Show the lengths of the urls and linkText strings. ---&gt;
&lt;cfoutput&gt;
	&lt;p&gt;&lt;strong&gt;Extract the url strings and the link text strings assuming each character is a single byte character&lt;/strong&gt;&lt;/p&gt;
	&lt;p&gt;&lt;cfloop collection=&quot;#str#&quot; item=&quot;elem&quot;&gt;
		&lt;cfset positionStart = 1&gt;
		&lt;strong&gt;#elem#&lt;/strong&gt;&lt;br /&gt;
		(length of string = #len(str[elem].text)#)&lt;br /&gt;
		(sum of reported lengths = #ArraySum(ListToArray(str[elem].lengths))#)&lt;br /&gt;
		&lt;cfloop from=&quot;1&quot; to=&quot;3&quot; index=&quot;i&quot;&gt;
			&lt;cfset u = mid(str[elem].text, positionStart, ListGetAt(str[elem].lengths,i))&gt;
			&lt;cfset positionStart = positionStart + ListGetAt(str[elem].lengths,i)&gt;
			&lt;span style=&quot;color:#str[elem].colour#;&quot;&gt;#u#&lt;/span&gt;&lt;br /&gt;
		&lt;/cfloop&gt;
	&lt;/cfloop&gt;&lt;/p&gt;
&lt;/cfoutput&gt;
&lt;/code&gt;

The question marks &apos;?&apos; are supposed to represent multibyte chars, unfortunately something on this environment means it is not retaining these chars.

Anyway I found that converting the string to bytes using getBytes(&quot;UTF-8&quot;) then using Java&apos;s &quot;java.util.Arrays&quot; and the &quot;copyOfRange()&quot; method meant I could extract the bytes I required and the using CF&apos;s CharsetEncode(&quot;UTF-8&quot;) convert the bytes back into a string. See below for the revised version.

&lt;code&gt;
&lt;!--- Show the lengths of the b_urls and b_linkText arrays. ---&gt;
&lt;cfoutput&gt;
	&lt;p&gt;&lt;strong&gt;Extract the url strings and the link text strings&lt;/strong&gt;&lt;/p&gt;
	&lt;cfset arr = CreateObject(&quot;java&quot;,&quot;java.util.Arrays&quot;)&gt;
	&lt;p&gt;&lt;cfloop collection=&quot;#str#&quot; item=&quot;elem&quot;&gt;
		&lt;cfset positionStart = 0&gt;
		&lt;cfset positionSum = 0&gt;
		&lt;strong&gt;#elem#&lt;/strong&gt;&lt;br /&gt;
		&lt;cfset b = str[elem].text.getBytes(&quot;utf-8&quot;)&gt;
		(length of byte array = #len(b)#)&lt;br /&gt;
		(sum of reported lengths = #ArraySum(ListToArray(str[elem].lengths))#)&lt;br /&gt;
		&lt;cfloop from=&quot;1&quot; to=&quot;3&quot; index=&quot;i&quot;&gt;
			&lt;cfset positionStart = positionSum&gt;
			&lt;cfset positionSum = positionSum + ListGetAt(str[elem].lengths,i)&gt;
			&lt;cfset ua = arr.copyOfRange(b, positionStart, positionSum)&gt;
			&lt;cfset u =  CharsetEncode(ua,&apos;utf-8&apos;)&gt;
		&lt;span style=&quot;color:#str[elem].colour#;&quot;&gt;#u#&lt;/span&gt;&lt;br /&gt;
		&lt;/cfloop&gt;
	&lt;/cfloop&gt;&lt;/p&gt;
&lt;/cfoutput&gt;
&lt;/code&gt;

Here is a link to the &lt;a href=&quot;/blog/multibyte.cfm&quot;&gt;sample&lt;/a&gt;.
				</description>
				
				<category>Java</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Tue, 13 Mar 2012 07:01:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2012/3/13/ColdFusion-extracting-substrings-using-the-Mid-function-and-multibyte-chars</guid>
				
				
			</item>
			
			<item>
				<title>ColdFusion, .Net (dotnet) and byte arrays</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2011/10/27/ColdFusion-Net-dotnet-and-reading-binary-files</link>
				<description>
				
				&lt;strong&gt;Problem:&lt;/strong&gt; Using ColdFusion&apos;s integration with .Net you can use &apos;System.IO.File&apos; to read in a file and get back the byte array of the file, however it is not a a byte array that you&apos;d expect i.e. a binary object. It is actually translated to an CF Array. This makes it difficult to use CF to deal with .Net byte arrays.

&lt;strong&gt;Solution:&lt;/strong&gt; However you can use .Net&apos;s &apos;System.Convert&apos; to convert it to a Base64 string, something CF can deal with.

See code below:

&lt;code&gt;
&lt;cfsetting showdebugoutput=&quot;false&quot;&gt;

&lt;!--- The file to read ---&gt;
&lt;cfset FilePath = &quot;C:\Projects\...\AnImage.jpg&quot;&gt;

&lt;!--- Read the file using .Net, returns a byte array. ---&gt;
&lt;cfset objFile = CreateObject(&quot;dotnet&quot;,&quot;System.IO.File&quot;)&gt;
&lt;cfset binaryFileDN = objFile.ReadAllBytes(FilePath)&gt;

&lt;!--- Read[binary] the same file using cffile. ---&gt;
&lt;cffile action=&quot;readbinary&quot; file=&quot;#FilePath#&quot; variable=&quot;binaryFileCF&quot;&gt; 

&lt;!--- Show the &apos;lengths&apos; of both objects. ---&gt;
&lt;cfoutput&gt;
CF binary length: #ArrayLen(binaryFileCF)#&lt;br /&gt;
.Net binary length: #ArrayLen(binaryFileDN)#&lt;br /&gt;&lt;br /&gt;
&lt;/cfoutput&gt;

&lt;!--- Show the dumps of each object. ---&gt;
&lt;cfdump var=&quot;#binaryFileCF#&quot; label=&quot;CF&quot;&gt;&lt;br /&gt;
&lt;cfdump var=&quot;#binaryFileDN#&quot; top=&quot;10&quot; label=&quot;.Net&quot;&gt;&lt;br /&gt;

&lt;!--- Take the .Net byte array and convert it to a Base64 string. ---&gt;  
&lt;cfset Convert = CreateObject(&quot;dotnet&quot;,&quot;System.Convert&quot;)&gt;
&lt;cfset BodyBase64 = Convert.ToBase64String(binaryFileDN)&gt;
&lt;cfset newBinaryFileDN = BinaryDecode(BodyBase64, &quot;base64&quot;)&gt;

&lt;cfdump var=&quot;#newBinaryFileDN#&quot; label=&quot;.Net&quot;&gt;
&lt;/code&gt;

The result looks something like this:

&lt;img src=&quot;http://www.stinkylittlefriend.com/blog/images/CF_DotNet_File.png&quot; /&gt;

Of course this is not limited to just reading binary files, anything that .Net returns as a byte array (e.g. &apos;System.Net.WebClient&apos; DownloadData()) and consequently gets translated by Java/ColdFusion as an &apos;Array&apos; can be treated the same way.
				</description>
				
				<category>.Net</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Thu, 27 Oct 2011 02:39:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2011/10/27/ColdFusion-Net-dotnet-and-reading-binary-files</guid>
				
				
			</item>
			
			<item>
				<title>ColdFusion, .Net (dotnet) and NTLM</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2011/10/18/ColdFusion-Net-dotnet-and-NTLM</link>
				<description>
				
				&lt;strong&gt;Problem:&lt;/strong&gt; Trying to make an HTTP request against a web site that has &lt;a href=&quot;http://en.wikipedia.org/wiki/Integrated_Windows_Authentication&quot;&gt;Intergated Windows Authentication (IWA) aka NTLM&lt;/a&gt; - sometimes CFHTTP just doesn&apos;t cut it.&lt;strong&gt;Solution:&lt;/strong&gt; Since IWA is associated to Microsoft products I thought I could use ColdFusion&apos;s .Net integration and actually use .Net to do the NTLM handshake that CFHTTP doesn&apos;t do.

In fact it didn&apos;t take long to piece together a very &apos;procedural heavy&apos; proof of concept. Using this as my &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/5t9y35bd.aspx&quot;&gt;primary reference&lt;/a&gt;.

I am in the process, right now, of rewriting my &apos;procedural heavy&apos; proof of concept so that it is more reusable and slightly fuller featured. 

Of course there are other HTTP-NTLM options that can be found on &lt;a href=&quot;http://www.riaforge.org/index.cfm?event=page.search#ntlm&quot;&gt;RIAForge&lt;/a&gt;
				</description>
				
				<category>.Net</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Tue, 18 Oct 2011 08:05:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2011/10/18/ColdFusion-Net-dotnet-and-NTLM</guid>
				
				
			</item>
			
			<item>
				<title>Convert epoch date to human readable date</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2011/5/4/Convert-epoch-date-to-human-readable-date</link>
				<description>
				
				I have a function that takes two arguments an epoch date and a date mask and it returns the formatted date.

The line that does all the work is:
&lt;code&gt;
&lt;cfset sFormattedDate = DateFormat( DateAdd(&quot;s&quot;,left(arguments.epoch,10),DateConvert(&quot;utc2Local&quot;, &quot;January 1 1970 00:00&quot;)), arguments.mask ) &gt;
&lt;/code&gt;

This works ... for epoch dates less than 19 January 2038.

My application recently started throwing an error when trying to convert 2177456400 to a date. So I needed a more robust way of converting an epoch date to an actual date.
&lt;code&gt;
&lt;cfset dateFormatter = CreateObject(&quot;java&quot;,&quot;java.text.SimpleDateFormat&quot;).init(arguments.mask)&gt;
&lt;cfset date = CreateObject( &quot;java&quot;, &quot;java.util.Date&quot; ).init(arguments.epoc*1000)&gt;
&lt;cfset sFormattedDate = dateFormatter.format(date)&gt;
&lt;/code&gt;

2177456400 is 01 Jan 2039.
				</description>
				
				<category>Java</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Wed, 04 May 2011 05:31:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2011/5/4/Convert-epoch-date-to-human-readable-date</guid>
				
				
			</item>
			
			<item>
				<title>Google getting into the wedding spirit</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2011/4/29/Google-getting-into-the-wedding-spirit</link>
				<description>
				
				Just seen that Google have added Mr and Mrs Pegman to Google StreetView for Wills and Kate.

&lt;img src=&quot;http://stinkylittlefriend.com/blog/images/wedding.jpg&quot; /&gt;
				</description>
				
				<category>Random</category>
				
				<pubDate>Fri, 29 Apr 2011 13:42:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2011/4/29/Google-getting-into-the-wedding-spirit</guid>
				
				
			</item>
			
			<item>
				<title>SQL to remove duplicates, keep most recent record</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2011/4/29/SQL--Remove-duplicates-keep-most-recent-record</link>
				<description>
				
				First off, I am not a DBA, although as a developer I have to write a lot of SQL. I have found, when writing SQL, especially when I am after a complicated dataset/recordset, that I have to get into the right mind set. 

Anyway I was faced with a problem where an existing database table had duplicate records. I wanted to delete the duplicates but keep the most recent record.Before I start deleting stuff I make sure I get the right dataset by creating the SELECT statement.

The table looked something like:
&lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;2&quot;&gt;
&lt;tr&gt;
&lt;td colspan=&quot;3&quot;&gt;&lt;strong&gt;TABLE_WITH_DUPLICATES&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&#xa0;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The unique ID (primary key) for each record calculated using a SEQUENCE (Oracle) - number incremented by 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&#xa0;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;GUID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A GUID that identifies the record non-unique column&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&#xa0;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;A bunch of other columns that aren&apos;t relevant&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

First thing I did was visualise the dataset I wanted i.e. using a subset of the existing data in the table I manually work out the result I am expecting, nothing too in-depth though. This helps me keep focus on the end result while writing the SQL.

So the next thing I did was write a normal select query that would help me find out the number of duplicates or occurrences, this will become the result set to base everything on:
&lt;code&gt;
SELECT 		guid, count(guid) as numoccurrences
FROM 		table_with_duplicates
GROUP BY 	guid
&lt;/code&gt;

Then using the resultset above I get the IDs and GUIDs of those records that have duplicates i.e. &apos;numoccurrences&apos; greater than 1. 
&lt;code&gt;
SELECT 		twd.id, occ.numoccurrences, twd.guid
FROM 		table_with_duplicates twd,
			(SELECT 		guid, count(guid) as numoccurrences
			 FROM 		table_with_duplicates
			 GROUP BY 	guid) occ
WHERE 			occ.numoccurrences &gt; 1
  AND			occ.guid = twd.guid
&lt;/code&gt;

So now I end up with all records (IDs, GUIDs, numoccurrences) that are duplicated.

As the IDs are unique and incremented I know for each duplicated set of records the highest ID is the most recent, if I had a timestamp column then I would probably have used that.

&lt;code&gt;
SELECT 		max(id) maxid, numoccurrences, guid
FROM 		(SELECT 		twd.id, occ.numoccurrences, twd.guid
			 FROM 		table_with_duplicates twd,
						(SELECT 	guid, count(guid) as numoccurrences
						 FROM 		table_with_duplicates
						 GROUP BY 	guid) occ
			 WHERE 			occ.numoccurrences &gt; 1
			   AND			occ.guid = twd.guid)
GROUP BY 	numoccurrences, guid
&lt;/code&gt;

So now I know what the highest ID value is for each duplicated set of results. I can now say get me all duplicate sets excluding the record with the highest ID in each duplicate set.

&lt;code&gt;
SELECT 		twd2.id, twd2.guid
FROM 		table_with_duplicates twd2,
		(SELECT 	max(id) maxid, numoccurrences, guid
		 FROM 		(SELECT 		twd.id, occ.numoccurrences, twd.guid
				 FROM 			table_with_duplicates twd,
							(SELECT 	guid, count(guid) as numoccurrences
							 FROM 		table_with_duplicates
							 GROUP BY 	guid) occ
				 WHERE 			occ.numoccurrences &gt; 1
				   AND			occ.guid = twd.guid)
		 GROUP BY 	numoccurrences, guid) findmaxid
WHERE 		twd2.guid = findmaxid.guid
  AND		twd2.id &lt;&gt; findmaxid.maxid
ORDER BY 	twd2.guid
&lt;/code&gt;

Then it is just a matter of plumbing this into a delete statement
&lt;code&gt;
DELETE FROM table_with_duplicates
WHERE ID IN (
SELECT 		twd2.id
FROM 		table_with_duplicates twd2,
		(SELECT 	max(id) maxid, numoccurrences, guid
		 FROM 		(SELECT 		twd.id, occ.numoccurrences, twd.guid
				 FROM 			table_with_duplicates twd,
							(SELECT 	guid, count(guid) as numoccurrences
							 FROM 		table_with_duplicates
							 GROUP BY 	guid) occ
				 WHERE 			occ.numoccurrences &gt; 1
				   AND			occ.guid = twd.guid)
		 GROUP BY 	numoccurrences, guid) findmaxid
WHERE 		twd2.guid = findmaxid.guid
  AND		twd2.id &lt;&gt; findmaxid.maxid
ORDER BY 	twd2.guid)
&lt;/code&gt;

And that is how complicated it is.
				</description>
				
				<category>SQL</category>
				
				<pubDate>Fri, 29 Apr 2011 09:57:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2011/4/29/SQL--Remove-duplicates-keep-most-recent-record</guid>
				
				
			</item>
			
			<item>
				<title>Recurse through folder structure to a specific depth</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2009/7/27/Recurse-through-folder-structure-to-a-specific-depth</link>
				<description>
				
				&lt;strong&gt;Problem:&lt;/strong&gt; A user at work wanted to copy an existing folder structure 3 levels deep and exclude all files. It would have been time consuming to create the folders manually and we couldn&apos;t copy &apos;n paste the folder structure because there was about 120GB of data and about 63,000 folders!&lt;strong&gt;Solution:&lt;/strong&gt; I did a bit of googling (as you do) and found Raymond Camden&apos;s blog entry &quot;&lt;a href =&quot;http://www.coldfusionjedi.com/index.cfm/2006/2/6/Ask-a-Jedi-Dumping-a-Recursive-Directory-List&quot; title=&quot;Dumping a Recursive Directory List&quot;&gt;Dumping a Recursive Directory List&lt;/a&gt;&quot; which helped. Although cfdirectory&apos;s recurse=&quot;yes&quot; would&apos;ve taken forever going through 63,000 folders and it also seemed like overkill especially if all the user wanted was the first few levels of the folder structure. 

So using Ray&apos;s example as a starting point I made a couple of minor tweaks and made it recurse through the top three levels. Initially I wanted to list out the directories like Ray had done. Once I was happy it was going to work as expected I then created the folder structure.

&lt;code&gt;
&lt;!--- Set file delimiter ---&gt;
&lt;cfset separator = createObject(&quot;java&quot;,&quot;java.io.File&quot;).separator&gt;

&lt;!--- Set your start directory ---&gt;
&lt;cfset sInitialDir = &quot;C:\tempProj&quot;&gt;

&lt;!--- Set where you want to copy the folder structure ---&gt;
&lt;cfset sCopyToDir = &quot;C:\tempProjRep&quot;&gt;

&lt;!--- Set the depth of recursion ---&gt;
&lt;cfset iDepth = 3&gt;

&lt;!--- Go and get folders ---&gt;
&lt;cfoutput&gt;#getFolders(sDirPath=sInitialDir, iDepth=iDepth, fCreate=true)#&lt;/cfoutput&gt;

&lt;cffunction name=&quot;getFolders&quot; output=&quot;false&quot; hint=&quot;Recurse through the folders to a user defined depth for a given directory.&quot;&gt;
	&lt;cfargument name=&quot;sDirPath&quot; type=&quot;string&quot; hint=&quot;The directory path to interogate.&quot; /&gt;
	&lt;cfargument name=&quot;iDepth&quot; type=&quot;numeric&quot; hint=&quot;The depth of recursion.&quot; /&gt;
	&lt;cfargument name=&quot;fCreate&quot; type=&quot;boolean&quot; default=&quot;false&quot; hint=&quot;Whether to create the folders or not.&quot; /&gt;
	
	&lt;cfset var iDecrement = arguments.iDepth - 1&gt;
	&lt;cfset var qryFiles = QueryNew(&quot;&quot;)&gt;
	&lt;cfset var qryDirOnly = QueryNew(&quot;&quot;)&gt;
	&lt;cfset var sOutput = &quot;&quot;&gt;
	&lt;cfset var sTempPath = &quot;&quot;&gt;
	
	&lt;cfdirectory directory=&quot;#arguments.sDirPath#&quot; recurse=&quot;no&quot; name=&quot;qryFiles&quot; sort=&quot;directory asc&quot;&gt;
	
	&lt;!--- Filter out files for the listing because we only want directories ---&gt;
	&lt;cfquery name=&quot;qryDirOnly&quot; dbtype=&quot;query&quot;&gt;
		SELECT 		*
		FROM 		qryFiles
		WHERE 		type = &apos;Dir&apos;
	&lt;/cfquery&gt;
	
	&lt;cfsavecontent variable=&quot;sOutput&quot;&gt;
		&lt;ul&gt;
		&lt;cfloop query=&quot;qryDirOnly&quot;&gt;
			&lt;!--- The location to copy the folder ---&gt;
			&lt;cfset sTempPath = Replace(directory, sInitialDir, sCopyToDir)&gt;
			&lt;li&gt;&lt;cfoutput&gt;Copy #directory##separator##name# to #sTempPath##separator##name#
				&lt;cfset fDirExists = DirectoryExists(sTempPath &amp; separator &amp; name)&gt; 
				&lt;cfif fDirExists&gt;
					(&lt;span style=&quot;color: ##CC0000; font-weight: bold;&quot;&gt;Warning! directory already exists.&lt;/span&gt;)
				&lt;cfelse&gt;
					(&lt;span style=&quot;color: ##00CC00; font-weight: bold;&quot;&gt;Ready!&lt;/span&gt;)
				&lt;/cfif&gt;
				&lt;!--- Create the folders if the user wants them created AND if the directories don&apos;t already exist ---&gt;
				&lt;cfif arguments.fCreate AND not fDirExists&gt;
					&lt;cftry&gt;
						Creating ...
						&lt;cfdirectory action=&quot;create&quot; directory=&quot;#sTempPath##separator##name#&quot;&gt;
						&lt;span style=&quot;color: ##00CC00; font-weight: bold;&quot;&gt;SUCCESS!&lt;/span&gt;
						&lt;cfcatch type=&quot;any&quot;&gt;
							&lt;span style=&quot;color: ##CC0000; font-weight: bold;&quot;&gt;FAILED!&lt;/span&gt; - #cfcatch.message#
						&lt;/cfcatch&gt;
					&lt;/cftry&gt;
				&lt;/cfif&gt;
				&lt;cfif iDecrement neq 0&gt;#getFolders(directory &amp; separator &amp; name, iDecrement, arguments.fCreate)#&lt;/cfif&gt;
			&lt;/cfoutput&gt;&lt;/li&gt;
		&lt;/cfloop&gt;
		&lt;/ul&gt;
	&lt;/cfsavecontent&gt;
	
	&lt;cfreturn sOutput /&gt;
&lt;/cffunction&gt;
&lt;/code&gt;
				</description>
				
				<category>ColdFusion</category>
				
				<pubDate>Mon, 27 Jul 2009 02:43:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2009/7/27/Recurse-through-folder-structure-to-a-specific-depth</guid>
				
				
			</item>
			
			<item>
				<title>How to get local drive information programmatically</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2009/6/19/How-to-get-local-drive-information-programmatically</link>
				<description>
				
				&lt;strong&gt;Problem:&lt;/strong&gt; You want to find out how much free space you have on your server&apos;s local drives. You also want to find out how much space you have used on your local drives. How can you do this programmatically?&lt;strong&gt;Assumptions:&lt;/strong&gt; You are using a Windows machine. You are using ColdFusion 8. 

&lt;strong&gt;Solution:&lt;/strong&gt; If you have .Net version 2 or greater AND the ColdFusion 8 .Net Service installed you can try using Ben Forta&apos;s &apos;&lt;a href=&quot;http://www.forta.com/blog/index.cfm/2007/5/30/GetDriveInfo-UDF-Powered-By-NET&quot; title=&quot;GetDriveInfo() UDF Powered By .NET&quot;&gt;GetDriveInfo() UDF Powered By .NET&lt;/a&gt;&apos;

Alternatively you can use this :

&lt;code&gt;
&lt;cfobject type=&quot;java&quot; action=&quot;create&quot; class=&quot;java.io.File&quot; name=&quot;objFile&quot;&gt;
&lt;cfobject type=&quot;java&quot; action=&quot;create&quot; class=&quot;javax.swing.filechooser.FileSystemView&quot; name=&quot;objFSVTemp&quot;&gt;

&lt;cfset arrRoots = objFile.listRoots()&gt;
&lt;cfset iArrayLen = ArrayLen(arrRoots)&gt;

&lt;cfset objFSV = objFSVTemp.getFileSystemView()&gt;

&lt;cfloop from=&quot;1&quot; to=&quot;#iArrayLen#&quot; index=&quot;i&quot;&gt;
	&lt;cfoutput&gt;
		&lt;strong&gt;Drive: #arrRoots[i]#&lt;/strong&gt;&lt;br /&gt;
		Available Space: #arrRoots[i].getFreeSpace()#&lt;br /&gt;
		Total Space: #arrRoots[i].getTotalSpace()#&lt;br /&gt;
		&lt;br /&gt;
	&lt;/cfoutput&gt;
&lt;/cfloop&gt;

&lt;cfdump var=&quot;#arrRoots#&quot;&gt;
&lt;cfdump var=&quot;#objFile#&quot;&gt;
&lt;cfdump var=&quot;#objFSV#&quot;&gt;
&lt;/code&gt;
				</description>
				
				<category>Java</category>
				
				<category>.Net</category>
				
				<category>ColdFusion</category>
				
				<pubDate>Fri, 19 Jun 2009 05:38:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2009/6/19/How-to-get-local-drive-information-programmatically</guid>
				
				
			</item>
			
			<item>
				<title>FireFox 2 Default Theme</title>
				<link>http://www.stinkylittlefriend.com/blog/index.cfm/2007/2/17/FireFox-2-Default-Theme</link>
				<description>
				
				Just in case you, like me, aren&apos;t really a fan of the default FireFox 2 &apos;Theme&apos; it is easy enough to change. 

Go to https://addons.mozilla.org/firefox/3479/ and download the &quot;Winestripe&quot; theme this is the theme that FireFox 1.5 used. Also you may not like the placing of the &apos;Close&apos; tab buttons. To change this go to &apos;about:config&apos; in your FF browser address bar scroll down to &apos;browser.tabs.closeButtons&apos; and change the value. The options are: 

0: Close appears on current open tab&lt;br /&gt;
1: Close appears on the right of each tab (default)&lt;br /&gt;
2: Close dissappears (middle click to close)&lt;br /&gt;
3: Close appears on the right of the browser

Happy customising FireFox :)
				</description>
				
				<category>FireFox</category>
				
				<pubDate>Sat, 17 Feb 2007 04:03:00 +0100</pubDate>
				<guid>http://www.stinkylittlefriend.com/blog/index.cfm/2007/2/17/FireFox-2-Default-Theme</guid>
				
				
			</item>
			</channel></rss>
