使用AJAX + Javascript以块的forms读取文件

所以,这是我的问题:我有一个大文本文件(大小约150 MB),有数十万行。我需要读取文件的内容,解析它,以便将行放入适当的html标记并写入它进入了一个window.document.open()对象。

我的代码适用于文件,直到50 MB的大小。

var rawFile=new XMLHttpRequest(); rawFile.open("GET",file, true); rawFile.onreadystatechange= function () { if (rawFile.readyState === 4) { if (rawFile.status === 200 || rawFile.status === 0) { var allText = rawFile.responseText; var contents = allText.split("\n"); var w = window.open(); w.document.open(); for (i = 0; i < contents.length; i++) { //logc so that str= appropriate tags + contents[i] w.document.write(str); } } } } 

代码有效。 逻辑有效。 但如果文件大小超过100MB或类似,Chrome崩溃。 我认为以块的forms读取文件,然后将其写入window.document.open()将为我删除此问题。

任何建议我如何能够完成这一点非常感谢。 谢谢 :)

(如果上面发布的代码中有任何错误,请忽略,我的实际代码非常大,所以我只写了一个微缩版本)

您的方法将削弱浏览器,因为您正在处理整个响应。 更好的方法是将进程中断,以便处理较小的块或者通过进程流式传输文件。

使用Fetch API而不是XMLHttpRequest可以访问流数据。 使用该流的一大优势是,当您处理内容时,您不会占用浏览器的内存。

以下代码概述了如何使用流来执行任务:

 var file_url = 'URL_TO_FILE'; // @link https://developer.mozilla.org/en-US/docs/Web/API/Request/Request var myRequest = new Request( file_url ); // fetch returns a promise fetch(myRequest) .then(function(response) { var contentLength = response.headers.get('Content-Length'); // response.body is a readable stream // @link https://docs.microsoft.com/en-us/microsoft-edge/dev-guide/performance/streams-api var myReader = response.body.getReader(); // the reader result will need to be decoded to text // @link https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder/TextDecoder var decoder = new TextDecoder(); // add decoded text to buffer for decoding var buffer = ''; // you could use the number of bytes received to implement a progress indicator var received = 0; // read() returns a promise myReader.read().then(function processResult(result) { // the result object contains two properties: // done - true if the stream is finished // value - the data if (result.done) { return; } // update the number of bytes received total received += result.value.length; // result.value is a Uint8Array so it will need to be decoded // buffer the decoded text before processing it buffer += decoder.decode(result.value, {stream: true}); /* process the buffer string */ // read the next piece of the stream and process the result return myReader.read().then(processResult); }) }) 

我没有实现处理缓冲区的代码,但算法如下:

 If the buffer contains a newline character: Split the buffer into an array of lines If there is still more data to read: Save the last array item because it may be an incomplete line Do this by setting the content of the buffer to that of the last array item Process each line in the array 

快速浏览一下Can I Use告诉我这在IE中不起作用,因为在Edge浏览器之前没有实现Fetch API。 然而,没有必要绝望,因为一些善良的灵魂已经为非支持浏览器实现了polyfill 。