【问题标题】:filereader api on big files大文件上的 filereader api
【发布时间】:2014-11-06 17:41:08
【问题描述】:

到目前为止,我的文件阅读器 api 代码一直运行良好,直到有一天我从我的一位客户那里得到了一个 280MB 的 txt 文件。页面在 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") ); }}

我在上面尝试做的是获取第一个换行符,以便我可以获得文件的列长度。我不应该把它当作文本阅读吗?如何在不破坏大文件页面的情况下获取文件的列长度?

【问题讨论】:

标签: javascript html filereader


【解决方案1】:

您的应用程序无法处理大文件,因为您在处理之前将完整文件读入内存。这种低效率可以通过流文件(读取小块)来解决,因此您只需将文件的一部分保存在内存中。

File 对象也是Blob 的一个实例,它提供.slice 方法来创建文件的较小视图。

这是一个假设输入为 ASCII 的示例(演示:http://jsfiddle.net/mw99v8d4/)。

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);
    }
}

前面的sn-p计算换行前的字节数。计算由多字节字符组成的文本中的字符数稍微困难一些,因为您必须考虑到块中的最后一个字节可能是多字节字符的一部分。

【讨论】:

  • 你正式成为我的英雄。起初,我有相同的想法,将它作为一个 blob 块来阅读,而不是阅读整个内容,但我没有足够的知识让它发挥作用。你不知道我是多么欣赏这一点。谢谢!
  • 如果我需要确定文件中的最后一个块,你会推荐什么?我正在使用的系统对最后一个块有不同的 REST api,然后提交整个文件。但我不知道如何确定最后一块。如果你不介意看我的问题,那会很有帮助stackoverflow.com/questions/39312451/…
  • 我想知道如何将其用于read n lines from a big file..... :/
  • 至于多字节字符困境,TextDecoder#decode now/soon 有一个 stream 选项标志用于此目的。
  • @RobW 我们如何逐块预览大图像?如果每个图像大小> 25mb,则显示多个图像的总大小约为900mb?我们如何在 img src 上逐块设置视图?
【解决方案2】:

有一个很棒的库,叫做Papa Parse,它以优雅的方式做到了这一点!它真的可以处理大文件,你也可以使用 web worker。

试试他们提供的演示:https://www.papaparse.com/demo

【讨论】:

  • CSV 解析器?这有帮助吗?
  • 当您想直接在浏览器中处理 CSV 文件而不是将其发送到后端时,这很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 2023-03-10
  • 2019-05-22
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
相关资源
最近更新 更多