I’m trying to read floats in javascript from a binary file that is created using Java.
The file is created in Java using DataOutputStream:
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); dos.writeFloat(-222); dos.writeFloat(222000); dos.writeFloat(130.329f); dos.flush(); dos.close();
The file is retreived by http request and read like this:
var client = new XMLHttpRequest(); client.addEventListener("load", dataLoaded); client.open("GET", "/ajax-requests.php?data=true", true); client.responseType = "arraybuffer"; client.send();
dataLoaded function:
function dataLoaded () { console.log("Float32Array: " + new Float32Array(this.response)); }
Output:
Float32Array: 3.3994099446055737e-41,1.8766110561523948e-38,0.00020218738063704222
Expecting:
Float32Array: -222,222000,130.329
The file is sent with php:
if(isset($_GET['data'])) { $file_path = "data/filename.ext"; if (file_exists($file_path)) { if(false !== ($handler = fopen($file_path, 'r'))) { header("Content-Type: application/octet-stream"); header("Content-Length: " . filesize($file_path)); readfile($file_path); } exit; } echo "<h1>Content error</h1><p>The file does not exist!</p>"; }
It seems that somewhere there is a flaw in the conversion but I can’t figure out where.
UPDATE:
The problem was just as Sean Van Gorder stated, a difference in endianness. To work around this I used DataView to read the arrayBuffer (since the file will be read both in java and in javascript this was the best sulotion)
var dataView = new DataView(arrayBuffer); console.log("dataView: " + dataView.getFloat32(0, false)); console.log("dataView: " + dataView.getFloat32(4, false)); console.log("dataView: " + dataView.getFloat32(8, false));
Output:
dataView: -222 dataView: 222000 dataView: 130.32899475097656
Advertisement
Answer
You’ve got a byte order mismatch. DataOutputStream writes in big-endian, but Float32Array usually reads in little-endian (depending on hardware). You’ll have to change the Java side or the Javascript side to match.