Javascript - 使用FileReader将二进制记录读入ArrayBuffers

时间:2013-01-22 00:56:11

标签: javascript html5 filereader

我有一个二进制数据文件,其中每个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);
  }
});

1 个答案:

答案 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测试。