我有一个二进制数据文件,其中每个x
字节都是一个记录,我有一些格式/掩码(但你更愿意看到它)来破译那些数据。就像,short short int short float double
,等等等等。所以我正在使用File API阅读此文件,我最终需要使用ArrayBuffer,但我还没有...所以我的问题是双重的。首先,最直接的是,从二进制文件到ArrayBuffer的每个x
字节读取的最佳方法是什么?
其次,因为我遇到了一些问题...... 为什么下面的脚本在读取500kb二进制文件时几乎立即填充5gb + RAM?
$('input[type="file"]').change(function(event) {
// FileList object
var files = event.target.files;
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
// closures and magnets, how do they work
reader.onload = (function(f) {
return function(event) {
// data file starts with header XML
// indexOf +9 for </HEADER> and +1 for null byte
var data_start = event.target.result.indexOf('</HEADER>')+10,
// leverage jQuery for XML
header = $(event.target.result.slice(0,data_start)),
rec_len = parseInt(header.find('REC_LEN').text(),10);
// var ArrayBuffer
// define ArrayBufferView
// loop through records
for (var i = data_start; i<event.target.result.length; i+=rec_len) {
// fill ArrayBuffer
// add data to global data []
console.log(i+' : '+event.target.result.slice(i, i+rec_len));
}
};
})(f);
// Read as Binary
reader.readAsBinaryString(f);
}
});
答案 0 :(得分:0)
至少有几个一般提示:
使用DataView是灵活的但有点慢 - 它应该比调用字符串parseInt
快但不如数组视图快。好处是它支持不同的字节顺序,如果您的二进制数据需要。使用reader.readAsArrayBuffer(f)
,然后在onload
回调中使用类似
var dv = new DataView(arrayBuffer, [startCoord, [endCoord]]),
result = [];
// in some loop for i...
result[i] = [];
result[i].push(dv.getInt8(coord));
// coord += offset;
result[i].push(dv.getFloat32(coord));
// end some loop
正如我所提到的,更快的是在ArrayBuffer上创建多个views,但你不能(据我所知)改变光标位置 - 所以你的混合数据类型将是一个问题。
要将结果放入类型化数组,只需声明var col1 = Uint8Array(length);
之类的内容即可。列出的类型数组子类here。请注意,根据我的经验,键入的数组在性能方面不会获得太多。谷歌正在对类型数组进行一些jsperf测试。