使用 Chrome,我正在尝试读取和处理本地磁盘上的一个大 (>4GB) 二进制文件。看起来 FileReader API 只会读取整个文件,但我需要能够以流的形式逐步读取文件。
该文件包含一个帧序列,其中包含一个 1 字节类型标识符、一个 2 字节帧长度、一个 8 字节时间戳,然后是一些具有基于类型的格式的二进制数据。这些帧的内容会被累积起来,我想用HTML5+JavaScript来生成图表,并根据这个文件的内容实时回放显示其他指标。
有人有什么想法吗?
使用 Chrome,我正在尝试读取和处理本地磁盘上的一个大 (>4GB) 二进制文件。看起来 FileReader API 只会读取整个文件,但我需要能够以流的形式逐步读取文件。
该文件包含一个帧序列,其中包含一个 1 字节类型标识符、一个 2 字节帧长度、一个 8 字节时间戳,然后是一些具有基于类型的格式的二进制数据。这些帧的内容会被累积起来,我想用HTML5+JavaScript来生成图表,并根据这个文件的内容实时回放显示其他指标。
有人有什么想法吗?
实际上,Files 是 Blob,并且 Blob 有一个 slice 方法,我们可以使用它来抓取更小的大文件块。
我上周编写了以下片段来过滤大型日志文件,但它显示了您可以用来在大文件中逐个子节循环的模式。
这是我使用的代码:
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() */
显然,您可以摆脱寻线,而只获取纯范围;我不确定你需要挖掘什么类型的数据,重要的是切片机制,上面以文本为中心的代码很好地证明了这一点。