Shaun Mccran

My digital playground

18
F
E
B
2009

Reading a file using a Java object

Sometimes in Coldfusion development its handy to use coldfusions standard functions such as CFfile or CFdirectory. But you can also invoke the underlying Java objects that share similar functionality. These can often be more efficient too, as there is no coldfusion server compilation layer involved.

For one piece of work I had recently I was reading a series of files, parsing them out and inserting a the collection of records into a database.

So I created used a java file reader object to read the files.

There is the odd extra config line in here, as the server pathing is unix based not windows based, and I'm dynamically reading the files from the directory.

view plain print about
1<cfset variables.dir = cgi.path_translated>
2<cfset variables.replaceVar = listlast(variables.dir, '\')>
3<cfset variables.dir = replaceNoCase(variables.dir, variables.replaceVar,'', 'all')>
4<cfset variables.filename = variables.dir & "datafile#url.fileNo#.txt">

Next I use the file name variable in the java FileReader object call. I wrap the file reader in a BufferedReader object as this greatly reduces the operation overhead of the FileReader object as the data is buffered into memory and not read from the disk.

Next I'll loop over the outptut string from the buffered file reader object, parsing each line and invoking the cfc method of 'processContent', passing in the string (line of data) as the argument 'content'. '

view plain print about
1<cfscript>
2        cnt = 0;
3        srcFile = variables.filename;
4    
5        // create a FileReader object
6
        fr = createObject("java","java.io.FileReader");
7        fr.init(srcFile);
8    
9        // create a BufferedReader object
10
        br = createObject("java","java.io.BufferedReader");
11        br.init(fr);
12        str = br.readLine();
13    
14        // writeOutput(str);
15
        while isDefinedd("str")) {
16            cnt = cnt + 1;
17            str = br.readLine();
18                if(isDefined("str")){
19                    //writeOutput(cnt);
20
                    //writeOutput(str);
21
                    // pass to CF to do the rest
22
                    processContent(str);
23                }
24            }
25        br.close();
26        //writeOutput(cnt);
27
    
</cfscript>

Now you can perform any sort of parsing you want to perform on the content. In the example below I am creating a local structure and populating it with each delimited value. This allows me to use standard notation to pick out individual elements for whatever processing you want.

view plain print about
1<cffunction name="processContent" output="true" hint="function for processing the file content">
2        <cfargument name="content" type="string">
3    
4        <cfset var local = structnew()>
5    
6        <cfset local.today = now()>
7
8        <cfset local.filecontent = replace(arguments.content,'\n',"", "all" )>
9    
10        <!--- list to array based on tab --->
11        <cfset local.data = local.filecontent.split("\t")>
12        <cfset local.variableName1 = local.data[1]>
13        <cfset local.variableName2 = local.data[2]>
14        
15        Etc...
16
17    </cffunction>

17
F
E
B
2009

Creating an MS Dos style text file directory listing - invoked with cfexecute

I have had a need in the past to list directory contents, and filter on the extension type within that directory.

You can do this using cfdirectory, but you can also use cfexecute to run a batch file, which in my experience is a quicker solution than having coldfusion reading large directories.

Create a batch file like this:

view plain print about
1dir \yourdir\*.* /s/b >dir.txt

"\yourdir\*.*" is optional you can filter this by file type by adding a file extension. EG \ or \*.log or \logs\*.*

"dir.txt" is the filename you want the listing to be stored in, choice of name/location is up to you. You can write it out to any directory that the server has permissions on.

eg mylogs.dat or \mylogs\list.txt

17
F
E
B
2009

CfHttp compression responses when calling a url - 360 Voice part 1

I was recently writing a service to consume an xml feed, and I stumbled upon an issue that I had previously not seen with the cfhttp tag. These days I would usually opt for a cfc call to a webservice, and consume it as a 'true' service object, but this is an old school http request, as I am reading asp page content. I setup the standard cfhttp code in coldfusion.

view plain print about
1<cfhttp url="http://www.360voice.com/api/blog-getentries.asp?tag=ect0z" method="GET">

Unfortunately the http response was "Connection Failure". After investigating various potential authentication issues from both the destination server and the source server I had hit a wall. I fired up 'HTTP debugger' and had a scan of the http responses to see if anything stood out, and discovered that the http response was actually '200' which signifies everything is ok. So I was actually receiving a valid response. Maybe the problem was coldfusion. It transpires that if CF receives compressed or encrypted http responses you have to tell it what to do with them manually.

view plain print about
1<cfhttpparam type="Header" name="Accept-Encoding" value="deflate;q=0">
2<cfhttpparam type="Header" name="TE" value="deflate;q=0">

By adding these headers to the cfhttp you are requesting that the server return uncompressed responses, allowing coldfusion to handle the data returned. I ended out piecing this together from several different sources, but this site (http://www.talkingtree.com/blog/index.cfm/2004/7/28/20040729) has a very good blog entry on this as well. So thanks Steven Erat, you helped a ton there!

Complete code:

view plain print about
1<cfhttp url="http://www.yourUrl.com" method="GET" charset="utf-8">
2<cfhttpparam type="Header" name="Accept-Encoding" value="deflate;q=0">
3<cfhttpparam type="Header" name="TE" value="deflate;q=0">
4</cfhttp>

Now on to why I was actually writing this cfhttp request in the first place, http://www.360voice.com/, where you can hook up your XBox 360 to a web data feed.

Like this.

02
F
E
B
2009

Coldfusion Server connectiong to SQL Server Express 2005

I've been using SQL Server Express for quite a while noa, and still prefer it to almost every other database application. I was rebuilding a development environment the other day, and discovered that I was using an ODBC "trusted connection" to connect to a SQL Server instance in Coldfusion Server. Why was this I thought?

It turns out that I'd had some problems getting Coldfusion to connect SQL Server datasource connection, so I'd used a custom ODBC connection. Looking into the connection error and having a dig around I found out a few things its worth checking when installing SQL Server.

1. First thing is to enable TCP/IP connectivity, as its not on by default. Go to Start -> All Programs -> Microsoft SQL Server 2005 -> Configuration Tools -> SQL Server Configuration Manager. Under SQL Server 2005 Network Configuration, click on Protocols for SQLEXPRESS, click on TCP/IP, and click enable. Then restart the service, which you can do from the Configuration Manager under the SQL Server 2005 Services area, or in windows services.

2. In my experience SQL Server always used to use port 1433 by default after installation. For some reason it hadn't used this port, it was using 1523. I was quite puzzled about this as I just used accepted the installation defaults. The port is a crucial setting when you're setting up your datasources for Coldfusion, otherwise CF wont even find the datasource, let alone attempt to connect. To check your port number, go to the SQL Server Configuration Manager, go to Network Configuration/Protocols again, right click on TCP/IP, choose Properties, then click on the IP Addresses tab. Look under IPAll in the TCP Dynamic Ports section. I personally wouldn't change this as I'm not really sure why SQL Server is using a different port now. I just used it in my Coldfusion datasource setup, and it connected fine.

_UNKNOWNTRANSLATION_ /