2014-01-15 88 views
2

您的浏览器如何决定触发FileReader.onprogress事件的频率?我在这个事件中做了一些处理,我认为它会更频繁地触发我想要的。我想要更大的块。有没有办法让它减少点火次数?FileReader.onprogress块大小

示例代码:

_.each(dropEvent.originalEvent.dataTransfer.files, function(file) { 
    var reader = new FileReader(); 
    var pos = 0; 
    var startTime = +new Date(); 
    var xxh = XXH(); 

    reader.onprogress = function(progress) { 
     var length = progress.loaded - pos; 
     var arr = new Uint8Array(reader.result, pos, length); 
     pos += length; 

     xxh.update(arr); 

     if (progress.lengthComputable) { 
      console.log('hashing', (progress.loaded/progress.total * 100).toFixed(1) + '%'); 
     } 
    }; 

    reader.onload = function() { 
     var arr = new Uint8Array(reader.result, pos); 
     xxh.update(arr); 
     var hash = xxh.digest().toNumber(); 

     var elapsed = +new Date() - startTime; 
     console.info("computed hash", xxh.digest().toNumber(), 'for file', file.name, 'in', elapsed, 'ms'); 
    }; 

    reader.readAsArrayBuffer(file); 
}); 

回答

4

我碰巧遇到这个老问题,而寻找到的另一个问题。
您可能不再需要解决方案,但这可能有助于未来的访问者。


您应该将文件分成更小的Blob,以便您可以指定所需的确切大小。

function hashFile(file, chunkSize, callback) { 
    var hash = XXH(); 
    var size = file.size; 
    var offset = 0; 
    var chunk = file.slice(offset, offset + chunkSize); 

    var hashChunk = function() { 
    var reader = new FileReader(); 
    reader.onload = function(e) { 
     // Increment hash 
     hash.update(e.target.result); 

     // Update offset for next chunk 
     offset += chunkSize; 

     // Hash next chunk if available 
     if(offset < size) { 
     // Splice the next Blob from the File 
     chunk = file.slice(offset, offset + chunkSize); 
     // Recurse to hash next chunk 
     hashChunk(); 
     // Done hashing 
     } else { 
     // Report digest 
     callback.call(file, hash.digest().toString(16)); 
     } 
    }; 

    reader.readAsArrayBuffer(chunk); 
    }; 

    // Start hashing chunks 
    hashChunk(); 
} 


演示http://jsbin.com/nococoqa/5/edit?js,console,output

+0

不'file.slice'使数据的实际拷贝?还是只是给你一个“查看”到文件数据?我想象前者比现在阅读要慢。 – mpen

+0

Blob和File对象是不可变的,它们应该引用相同的字节数组。即使性能受到影响,您也可以通过不将整个文件加载到内存中来节省内存。一旦一个块被散列,它就会被GC拾取。这使您可以散列多个GB文件。 – Syntax

+0

我并不认为'readAsArrayBuffer'将所有内容都读入内存中 - 我认为这是'onProgress'的目的。这也许可以解释为什么我的大文件需要这么长时间,或者为什么在启动时有一些延迟。我必须给你的解决方案一个旋风。谢谢! – mpen