到目前为止,我的文件阅读器api代码一直运行良好,直到有一天,我从一个客户端获得了280MB的txt文件。Page只是在Chrome和Firefox中直接崩溃了,没有任何反应。
// create new reader object var fileReader = new FileReader(); // read the file as text fileReader.readAsText( $files[i] ); fileReader.onload = function(e) { // read all the information about the file // do sanity checks here etc... $timeout( function() { // var fileContent = e.target.result; // get the first line var firstLine = e.target.result.slice(0, e.target.result.indexOf("\n") ); }}
我上面想要做的是获取第一个换行符,以便我可以获取文件的列长。我不应该以文字形式阅读吗?如何在不破坏大文件页面的情况下获取文件的列长?
您的应用程序无法处理大文件,因为您在处理之前将整个文件读入内存。这种低效率可以通过流式传输文件(读取小块)来解决,因此您只需要在内存中保留文件的一部分即可。
甲File对象也是一个实例Blob,它提供了.slice创建文件的较小视图的方法。
File
Blob
.slice
function findColumnLength(file, callback) { // 1 KB at a time, because we expect that the column will probably small. var CHUNK_SIZE = 1024; var offset = 0; var fr = new FileReader(); fr.onload = function() { var view = new Uint8Array(fr.result); for (var i = 0; i < view.length; ++i) { if (view[i] === 10 || view[i] === 13) { // \n = 10 and \r = 13 // column length = offset + position of \r or \n callback(offset + i); return; } } // \r or \n not found, continue seeking. offset += CHUNK_SIZE; seek(); }; fr.onerror = function() { // Cannot read file... Do something, e.g. assume column size = 0. callback(0); }; seek(); function seek() { if (offset >= file.size) { // No \r or \n found. The column size is equal to the full // file size callback(file.size); return; } var slice = file.slice(offset, offset + CHUNK_SIZE); fr.readAsArrayBuffer(slice); } }
上一个代码段计算换行之前的字节数。计算由多字节字符组成的文本中的字符数稍微困难一点,因为您必须考虑到块中的最后一个字节可能是多字节字符的一部分的可能性。