I was just reading over on CF-Talk that Shane Trahan was trying to split a binary file, write both parts to disk, and then later read them in and re-join them. I have never done anything like this, so I thought I would give it a try.
At first, I was going to use a few ColdFusion arrays, but that didn't seem to work. For one, ColdFusion arrays are not really arrays, they are Java Collections. Additionally, I think there were some data type conversions taking place that I was not away of. I don't know enough about Java to full understand all the data type stuff.
After a little bit of Googling, I found the Java ByteBuffer. This finally solved the problem! The ByteBuffer does all the heavy lifting for splitting and then joining the underlying byte arrays of the binary file. Check out my solution below:
Launch code in new window » Download code as text file »
Now, I am not sure if this is a good way to do it, but the code seems fairly straight forward.
Download Code Snippet ZIP File
Comments (7) | Post Comment | Ask Ben | Permalink | Other Searches | Print Page
I'm assuming the file splitting is for BLOBs?
Posted by Todd Rafferty on Oct 31, 2007 at 3:25 PM
@Todd,
To be honest, I am not sure what the original intent was. However, I assume that it all shows up as a byte array in one form or another, so I guess whether it's a BLOB or binary file read, the same algorithm (or slightly modified) can be used.
Posted by Ben Nadel on Oct 31, 2007 at 3:28 PM
Another excellent example of ColdFusion and Java rocking like it's 1999. Much obliged!
Splitting and joining binary files is quite useful when you're uploading or downloading files. You can also build a file one byte at a time with classes like BufferedInputStream, but that's a whole other story. :)
You used ArrayLen to get the size of the binary file. Any idea on how exactly this works?
Posted by David Stamm on Nov 1, 2007 at 2:11 PM
I just noticed: your comment for the first CreateObject call says: "Create an instance of the static ByteBuffer class so that we can refer to it multiple times."
I think it's more accurate to say you are loading the ByteBuffer class so that you can call its static methods.
Static methods are the closest that Java comes to global functions. The methods are not called on a particular ByteBuffer object (or instance) - they're just there.
Posted by David Stamm on Nov 1, 2007 at 2:14 PM
@Dave,
ArrayLen() works because I think the binary file is loaded as a proper Java array of the bytes. I say "proper" array because it's not a ColdFusion array (Collection), it's a real byte array as in Byte[] ... I think :)
This is all just guess work for me, though. I defer to you for the better Java explanation as your Java experience eclipses mine.
Posted by Ben Nadel on Nov 2, 2007 at 7:23 AM
@Ben,
I just took a binary variable created with <cffile action="readbinary"> and looked under the hood with my handy getClassInfo() reflection function. The variable is an instance of this Java class:
[B
WTF? Anyone know what a [B is? Some sort of pointer? The class implements the Serializable and Cloneable interfaces, if that is any help.
Posted by David Stamm on Nov 2, 2007 at 10:19 AM
@Dave,
I believe the "[" indicates an array and whatever comes after it is the type of array. Like sometimes, I think I get "[String" which is an array of strings.
Posted by Ben Nadel on Nov 2, 2007 at 10:27 AM