在JavaScript中逐步读取二进制文件

Progressively read binary file in JavaScript

本文关键字:读取 二进制文件 JavaScript      更新时间:2023-09-26

使用Chrome,我正在尝试读取和处理本地磁盘上的一个大(>4GB)二进制文件。看起来FileReader API只会读取整个文件,但我需要能够以流的形式逐渐读取文件。

该文件包含一系列帧,其中包含1字节的类型标识符、2字节的帧长度、8字节的时间戳,以及一些具有基于类型的格式的二进制数据。这些帧的内容将被累积,我想使用HTML5+JavaScript生成图形,并根据该文件的内容实时播放其他指标。

有人有什么想法吗?

实际上,文件是Blob,Blob有一个slice方法,我们可以用它来获取大块文件中的小块。

上周我写了下面的截图来过滤大的日志文件,但它显示了可以使用的模式,可以通过大文件逐小节循环。

  1. file是文件对象
  2. fnLineFilter是一个函数,它接受文件的一行并返回true以保留它
  3. fnComplete是一个回调,其中收集的行作为数组传递

这是我使用的代码:

 function fileFilter(file, fnLineFilter, fnComplete) {
     var bPos = 0,
         mx = file.size,
         BUFF_SIZE = 262144,
         i = 0,
         collection = [],
         lineCount = 0;
     var d1 = +new Date;
     var remainder = "";
     function grabNextChunk() {
         var myBlob = file.slice(BUFF_SIZE * i, (BUFF_SIZE * i) + BUFF_SIZE, file.type);
         i++;
         var fr = new FileReader();
         fr.onload = function(e) {
             //run line filter:
             var str = remainder + e.target.result,
                 o = str,
                 r = str.split(/'r?'n/);
             remainder = r.slice(-1)[0];
             r.pop();
             lineCount += r.length;
             var rez = r.map(fnLineFilter).filter(Boolean);
             if (rez.length) {
                 [].push.apply(collection, rez);
             } /* end if */
             if ((BUFF_SIZE * i) > mx) {
                 fnComplete(collection);
                 console.log("filtered " + file.name + " in " + (+new Date() - d1) + "ms  ");
             } /* end if((BUFF_SIZE * i) > mx) */
             else {
                 setTimeout(grabNextChunk, 0);
             }
         };
         fr.readAsText(myBlob, myBlob.type);
     } /* end grabNextChunk() */
     grabNextChunk();
 } /* end fileFilter() */

很明显,您可以摆脱寻线,而只获取纯范围;我不确定你需要挖掘什么类型的数据,重要的是切片机制,上面以文本为中心的代码很好地证明了这一点。