Friday, 27 July 2012

How do I know if this variable is a file handle?

G'day
I'm not going to make a habit of making two posts in one day, but this quandary has just presented itself, so I'm gonna ask about it on StackOverflow, the Adobe forums, and Twitter (via this post).

I have this code:

This is a version of the code from my earlier post, having been fixed slightly as per Simon Baynes's observation that I had a spurious catch() block in the original.

Anyway, there's another bug in it: if there was an error during the fileOpen(), then the file variable won't be a file handle, so the fileClose() in the finally block will error.  Oops.

So I need to identify whether the file variable is actually a file handle, and iff it is, then close it.



But ColdFusion has no function isFile().  Or anything like that.  There's no isValid("file", someVar) or anything like that.  I can't do fileExists() on it (I didn't expect that to work, but I tried on a whim).

For the given example, I can just do this:

if (file != ""){
    fileClose(file);
}


And that's fine for my purposes here, but it's not a great answer.

So how does one know whether a variable is a file or not?

If one dumps a file handle, one gets this:

File : isFile.cfm
lastmodified{ts '2012-07-27 17:31:44'}
moderead
nameisFile.cfm
pathC:\ColdFusion10\cfusion\wwwroot\shared\CF\CFML\functions\filesystem\fileOpen\isFile.cfm
size161
statusopen

 It looks like a struct, but it's not.  This returns false:

<cfoutput>#isStruct(file)#</cfoutput>


However this returns true:

writeOutput(isObject(f) && structkeyExists(f, "status") && f.status == "open");


So one could do that, but it's still only an approximation of actually identifying a file handle (a CFC instance that happens to expose a status variable with value "open" would pass this test, as coincidental as that would be.

This is something:

writeOutput(f.getClass().getName());

This outputs:

coldfusion.tagext.io.FileStreamWrapper.

So that's a way to actually work out if it's a file.  But it's not native CFML, so is "cheating" a bit.

Surely there really ought to be an isFile() function?  Should I raise a bug for that do you think?

Or is there already a way to do this I am unaware of?

Update:

I'd raised a ticket for this - 3299625 - and it's been marked as fixed. In ColdFusion 11, there'll be a isFileObject() function. Nice one!


Cheers for any hints or tips people offer.


--
Adam