0

我有一个二进制数据文件,其中每个x字节都是一条记录,并且我有一些格式/掩码(但是您更喜欢看到它)来破译该数据。这就像short short int short float double,,,废话。所以我正在使用File API读取这个文件,我最终需要使用ArrayBuffer,但我还没有……所以我的问题有两个。首先,也是最直接的,将二进制文件中的每个字节读x入 ArrayBuffer 的最佳方法是什么?

其次,当我遇到一些问题时......为什么下面的脚本在读取 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);
  }
});
4

1 回答 1

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 上创建多个视图,但是(据我所知)您不能随时更改光标位置——因此您的混合数据类型将是一个问题。

要将结果放入类型数组中,只需声明类似var col1 = Uint8Array(length);. 这里列出了类型化数组的子类。请注意,根据我的经验,类型化数组在性能方面不会给您带来太多好处。谷歌搜索一些类型化数组的 jsperf 测试。

于 2013-02-13T17:56:42.260 回答