How to get file attributes in ColdFusion 7? - coldfusion

I cannot find a function that tells me the attributes of a given file. I specifically need to get the file's size. How do I find this info.?
edit:
I think I found an answer, just not the answer I was hoping for:
So far till ColdFusion 7, there was no
good way to find information like
size, last modified date etc about a
file. Only way you could do that was
to use cfdirectory tag to list the
directory, get the query from it, loop
over the query until you hit the
desired file and then fetch the
required metadata.
http://coldfused.blogspot.com/2007/07/new-file-io-in-coldfusion-8-part-ii.html
Anyone know of a better way?

I believe cfdirectory is your simplest answer - but note, you can use the filter attribute as your filename, and you won't have to loop over the result.

<cffunction name="getFileSize">
<cfargument name="filepath">
<cfreturn createObject("java","java.io.File").init(Arguments.filepath).length()>
</cffunction>

The CFLib FileSysLibrary has a bunch of file functions.
FileSize
FileSizeCOM
May be of particular interest

Related

Coldfusion 8 how do I get a data log in a cfscript tag?

So I have a cfscript tag that runs some XML data through but I'm getting an error on one of my executes its getting weird data it cant use, I am trying to find out what this data is however, all of my attempts to cfdump this data have failed miserably. Does anyone know of a way to get a data log from inside cfscript data?
I've tried:
-Ending the script writing the dump and restarting the script
-ending the script writing the dump and aborting
-putting the dump at the end of the cfscript
I'm running out of ideas. Thank you ahead of time!
Here's are my tips:
First, create a UDF in tag format - I call my "sdump":
<cfunction name="sdump">
<cfargument name="anyvar" required="true"/>
<cfdump var="#anyvar#"/>
</cffunction>
Then in your cfscript while debugging you can simply do:
<cfscript>
sdump(myProblemobject);
</cfscript>
That keeps you from having to break your script block all the time. I actually include mine in a CFC library of functions that's loaded in Onrequest.
Second, sometimes cfdump doesn't play nice with complex XML. It's gotten really smart in CF 9 and later, but I remember CF8 not always loving complicated XML. In that case you have to use your noggin.
For example, try using toString() on the XML object itself and dumping it in source as in tmpvar = toString(myXml); This is more useful if you split out the specific node that is causing you problems into it's own little xml object. Then use dump or (if dump fails) try "writeoutput();" - which is made like a cfoutput for cfscript - like so:
<cfscript>
xmlTmp = toString(myXml);
writeoutput(xmlTmp);
</cfscript>
Working your way through the xml attribute by attribute and node by node might be tediuous, but it might be easier than walking your eyballs through the raw XML looking for issues.
Remember too that you can validate your XML document or var using the various isXML() functions native to CF (isXML(), isXMLAttribute() etc.). Not sure what the list looked like in CF8. Good luck - these sort of problems are always trial and error I'm afraid. :)

Can't delete Solr keys

Having trouble deleting keys from a Solr collection for files.
Updating the Solr collection with this:
<cfoutput query="fileQuery">
<cfset theFile = defaultpath & "#fileID#.pdf" />
<cfif fileExists(theFile)>
<cfindex
action="update"
collection="file_vault_solr"
type="file"
key="#theFile#"
title="#documentName#"
body="fileNumber,documentName"
custom1="/filevault/#filealias#"
custom2="#fileNumber#"
custom3="#documentName#"
>
</cfif>
</cfoutput>
However, when attempting to delete the key from the catalog it simply doesn't work. Here's the code being used to (try to) delete the keys:
<cfoutput query="deletedFile">
<cfset theFile = defaultpath & "#fileID#.pdf" />
<!--- Remove the deleted file from the collection. --->
<cfindex
collection="file_vault_solr"
type="file"
action="Delete"
key="#theFile#"
>
</cfoutput>
The key is not deleted, however. The only thing that has worked has been to purge the whole catalog and re-index all of the documents.
Any insights?
After a lot of debugging I found out.
The reason for this behavior is a very… uh… unfortunate uhm… "design decision" Adobe took when implementing the interface between ColdFusion and Solr.
So you have a Solr collection of indexed files and want to selectively purge the ones that do no longer exist on disk. I'm pretty sure that's the exact situation you've been in.
Let's assume:
there is a file called /path/to/file on your system and
it is indexed in the Solr collection foo.
When you issue a <cfindex collection="foo" action="delete" key="/path/to/file">, ColdFusion sends the following HTTP request to Solr:
POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>1247603285</id></delete>
This is a perfectly reasonable request that Solr will happily fulfill. The only strange thing is the number in the <id>. In any case, the file will be gone from the index after this operation.
Re-index the file and delete it from disk. Now:
there no longer is a file called /path/to/file on your system, but
it is still indexed in the Solr collection foo.
Let's do the same <cfindex action="delete"> operation again.
POST /solr/foo/update?wt=xml&version=2.2 (application/xml; charset=UTF-8)
<delete><id>/path/to/file</id></delete>
Huh? Shouldn't there be a number in the ID?
As it turns out, someone at Adobe thought it would be a jolly smart idea to use numbers for unique IDs of indexed files, to, uhhh, save space, I assume.
However for some inexplicable reason this only happens when the file in question still exists. If it does not exist anymore, ColdFusion will notice and pass the path instead.
Inspecting the number reveals that it would fit into a 32 bit signed integer value. (I've checked, there are plenty of negative values in the uid field of the collection.)
So this looks as if they use some kind of hashing algorithm that returns 32 bits and chuck that in a int. CRC32 springs to mind, but that's not it. Also, java.util.zip.CRC32 returns a long, so there wouldn't be any negative values in the first place.
The other readily available 32 bit hash in Java is ... java.lang.Object.hashCode().
Bingo.
"/path/to/file".hashCode() // -> 1247603285
So the solution is to never delete a file by its path, but always like this:
<cfindex collection="foo" action="delete" key="#path.hashCode()#">
For files that no longer exist this does the right thing.
More importantly: For files that still exist this does the right thing as well - ColdFusion would have sent the hash code anyway.
Until Adobe fixes this problem this is a safe and easy work-around.
Note that the file path is case sensitive and must match exactly with the one stored in the index.
A quick
<cfsearch collection="foo" name="foo">
without any criteria will return all index entries, so retrieving the exact path of orphaned entries it not a big problem.
Eric Lippert explains object hash codes and why it is a bad idea to use them for anything "practical" in an application It's a .NET article but applies to Java just as well.
It boils down to: Adobe should store the actual path in the Solr collection and leave the performance optimization they seem to have attempted to Solr.
I've filed Bug 3589991 against Adobe's ColdFusion bug database.
The key has to match exactly what is in Solr's index. So ensure that "defaultpath" is the same in both and check that the case matches as I believe Solr is case sensitive.
To debug this I would suggest that you add the status="myStatusVar" to the cfindex call . Then on both the add and delete to see what is going on. If the delete is not returning a Deleted Count. Then there is a Key mismatch.
<cfindex
collection="file_vault_solr"
type="file"
action="Delete"
key="#theFile#"
status="myStatusVar"
>

Is it possible to download a file variable in coldfusion?

Using Coldfusion's SpreadSheet() object I have created an excel file and now the user needs to be able to download it.
mySS = SpreadsheetNew();
format1 = StructNew();
format1.color="dark_green";
format1.size="24";
SpreadSheetSetCellValue(mySS, 7,2,3);
SpreadSheetFormatCell(mySS, format1, 2, 3);
essentially I would like something like
<cfdownload var="#mySS#">
however it's almost never that simple. I realize that I can write the file and then use cfheader \ cfcontent however I am trying to avoid writing the file if possible.
Edit
Based on the suggestion I got from speshak I tried
<cfcontent variable="#mySS#" type="application/msexcel">
and the error I got was, am I missing something?
coldfusion.excel.ExcelInfo is not a supported variable type. The
variable is expected to contain binary data.
Alright so thanks to Raymond Camden's Post and speshak here is the final solution.
<cfheader name="Content-Disposition" value="attachment;filename=filename.xls">
<cfcontent variable="#spreadsheetReadBinary(mySS)#" type="application/msexcel">
Try:
<cfcontent variable="#mySS#">
You probably want to set the type attribute as well so the browser knows it's not HTML.

List of tags not available ColdFusion 9 script syntax?

I'm looking for a complete list of tags that are not available in ColdFusion 9 script syntax.
Example:
CFSetting: is one example that is available in Railo but not in CF9 for use in cfscript
CFDocument: I can't find this one so far.
Not an official list by any measure, but this is a list I presented to a private forum a while back, and it didn't receive too much correction (and those corrections have been integrated). It was in the context of what CF does and doesn't need to be implemented, to claim 100% coverage in CFScript.
Summary of omissions:
These ones are significant omissions:
<cfcollection>
<cfexchangecalendar>
<cfexchangeconnection>
<cfexchangecontact>
<cfexchangefilter>
<cfexchangemail>
<cfexchangetask>
<cfexecute>
<cfindex>
<cfinvoke> (support for dynamic method names)
<cflogin>
<cfloginuser>
<cflogout>
<cfmodule>
<cfoutput> (implementation of query looping with grouping)
<cfparam> (fix the bug in that enforced requiredness doesn’t work (ie: param name="foo";))
<cfsearch>
<cfsetting>
<cfwddx>
<cfzip>
<cfzipparam>
There’s a reasonable case for these ones to be implemented:
<cfassociate>
<cfcache>
<cfcontent>
<cfflush>
<cfhtmlhead>
<cfheader>
<cfntauthenticate>
<cfprint>
<cfschedule>
<cfsharepoint>
These ones... I’m ambivalent:
<cfgridupdate>
<cfinsert>
<cfobjectcache>
<cfregistry>
<cfreport>
<cfreportparam>
<cftimer>
<cfupdate>
We don’t need these ones at all, I think:
<cfajaximport>
<cfajaxproxy>
<cfapplet>
<cfcalendar>
<cfchart>
<cfchartdata>
<cfchartseries>
<cfcol>
<cfdiv>
<cfdocument>
<cfdocumentitem>
<cfdocumentsection>
<cffileupload>
<cfform>
<cfformgroup>
<cfformitem>
<cfgraph>
<cfgraphdata>
<cfgrid>
<cfgridcolumn>
<cfgridrow>
<cfinput>
<cflayout>
<cflayoutarea>
<cfmap>
<cfmapitem>
<cfmediaplayer>
<cfmenu>
<cfmenuitem>
<cfpod>
<cfpresentation>
<cfpresentationslide>
<cfpresenter>
<cfselect>
<cfsilent>
<cfslider>
<cfsprydataset>
<cftable>
<cftextarea>
<cftextinput>
<cftooltip>
<cftree>
<cftreeitem>
<cfwindow>
If there's anything here that you think ought to be included in CFScript, please raise an issue here - http://cfbugs.adobe.com/cfbugreport/flexbugui/cfbugtracker/main.html - and cross reference the issue number here.
HTH.
I would argue that there are no commands that are not available as script as you can extend and write the missing bits using cfc's.
Thus wrap your favourite missing <cftag in a cfc and call it using new
However, here is a list of what is supported
http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSe9cbe5cf462523a02805926a1237efcbfd5-7ffe.html

store data in array

I have used cfhttp to read a .cfm file, but I want to store the data in one variable or array and pass this variable to a cfchart to display it in chart format. How can I do this?
Use XMLParse and then pull the information you need out of the XML Object and put it into an array or struct or what ever format you need.
As an aside you need to take a look at the online references I've been giving you before asking a question and you also need to mark the previous questions you've asked as answered.
The answer to this will depend on what the .cfm page is returning. If the returned value is XML, then #stephen is pretty much dead on. XMLParse will convert well-formed XML into nested structures and arrays. You can dump them to view the structure, and loop over them to insert it into the array you need.
If the .cfm page returns a list, you can use listToArray() to convert that directly into an array.
If you get name-value pairs, you'll have to do a little work to assign the data correctly, but there are several approaches.
If you edit your question to include more info about the data being returned, and maybe a sample of both the data and what you need it transformed into, we could probably give more specific advice.
Depending on just exactly what your accessing on the .cfm page you're loading via cfhttp, you could try something like:
<cfhttp method="Get"
url="somepage.cfm"
result="myResult">
<cfset PageLoad = ArrayNew(1) />
<cfset PageLoad = #ArrayAppend(PageLoad, myResult.FileContent)# />
I use a variation of that code to return and store a call/response to my custom url shortener...
Hope it helps!