Chrome,FileReader API,event.target.result ===“" [英] Chrome, FileReader API, event.target.result === ""

查看:145
本文介绍了Chrome,FileReader API,event.target.result ===“"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web应用程序,它可以通过FileReader处理大文本文件(> 500mb).使用readAsText.已经工作了好几年,但是突然间我得到了空洞的回应. Event.target.result是一个空字符串. 369mb的作品. 589mb不起作用.我已经在多台计算机上进行了测试.结果相同.

I have a web app which has processing big text-files (> 500mb) via FileReader. Using readAsText. Has been working great for years but suddenly I get empty response. Event.target.result is an empty string. 369mb works. 589mb does not work. I've tested on multiple computers. Same result.

它在FireFox中有效.

It works in FireFox.

Chrome浏览器必须在最近的更新中对此进行了介绍.

Chrome must have introduced this in a recent update.

此错误是否已提交?

有什么解决方法吗?

推荐答案

这是v8对字符串长度的限制.

此错误是否已提交?

Has this bug been submitted?

这是负责任的提交: https://github.com/v8/v8/commit /ea56bf5513d0cbd2a35a9035c5c2996272b8b728

我在上遇到的二等分>,并发现它已在Chrome v79上应用.

Running a bisect I felt on this Change-Log and found it was applied on Chrome v79.

在此更改之前,将64位平台上的限制设置为1024MB,新的限制是512MB(一半).

Before this change the limit on 64-bits platforms was set to 1024MB, the new limit is 512MB, the half.

这意味着不仅FileReader受到影响,而且任何尝试产生如此大的String的方法也将受到影响.

This means not only FileReader is affected, but any method that would try to produce such a big String.

这是一个简单的例子:

const header = 24;
const bytes = new Uint8Array( (512 * 1024 * 1024) - header );
let txt = new TextDecoder().decode( bytes );
console.log( txt.length ); // 536870888
txt += "f"; // RangeError

有什么解决方法吗?

Is there any workaround?

解决该问题的唯一方法是按块处理文本.

The only way around that issue is to process your text by chunks.

幸运的是,您正在处理ASCII数据,因此您可以轻松地使用

Luckily, you are dealing with ASCII data, so you can easily split your resource and work on that chunk using the Blob.slice() method:

// working in a Web-Worker to not freeze the tab while generating the data
const worker_script = `
(async () => {

  postMessage( 'Generating file, may take some time...' );

  const bytes = Uint8Array.from(
    { length: 800 * 1024 * 1024 },
    (_, i) => (i % 25) + 65
  );
  const blob = new Blob( [ bytes ] );

  const length = blob.size;
  const chunk_size = 128 * 1024 * 1024;

  postMessage( 'Original file size: ' + length );
  
  let As = 0;
  let i = 0;
  while ( i < length ) {
    const str = await blob.slice( i, i + chunk_size ).text();
    i += chunk_size;
    As += str.split( 'A' ).length - 1;
  }
  postMessage( 'found ' + As + ' "A"s in the whole file' );

} )();
`;
const worker_blob = new Blob( [ worker_script ] );
const worker = new Worker( URL.createObjectURL( worker_blob ) );
worker.onmessage = (evt) => console.log( evt.data );

使用诸如UTF-8之类的富文本格式的文本必须处理多字节字符,而这可能不是那么容易...

The ones working with rich text like UTF-8 would have to deal with multi-bytes characters, and this may not be that easy...

还要注意,即使在允许您生成如此大的字符串的浏览器中,您也可能会面临其他问题.例如,在Safari中,您可以生成更大的字符串,但是如果将其保留在内存中的时间过长,则浏览器将自动重新加载页面.

Also note that even in browsers that let you generate such big strings, you may very well face other problems too. For instance in Safari, you can generate bigger strings, but if you keep it alive too long in memory, then the browser will reload your page automaticaly.

这篇关于Chrome,FileReader API,event.target.result ===“"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆