FileReader memory leak
by andy250
HTML
<input id="fu" type="file" multiple="multiple" />
<br/>
<br/>
<div class="sent"></div>
<br/>
<div class="pb"></div>
CSS
.pb {
height: 10px;
width: 0%;
background-color: green;
}
JavaScript
var reader = new FileReader();
var fu = {
file: null,
chunks: [],
chunkSize: 5000000,
chunkNo: 0,
totalChunks: 0,
chunkify: function() {
fu.totalChunks = Math.ceil(fu.file.size / fu.chunkSize);
var seq = 0;
while (seq < fu.totalChunks) {
var start = seq * fu.chunkSize;
var end = Math.min(start + fu.chunkSize, fu.file.size);
if (start <= end) {
fu.chunks.push(fu.file.slice(start, end, fu.file.type));
}
seq++;
}
},
select: function(evt) {
evt.stopPropagation();
evt.preventDefault();
fu.file = evt.target.files ? evt.target.files[0] : evt.dataTransfer ? evt.dataTransfer.files[0] : null;
fu.chunkify();
fu.chunkNo = 0;
fu.processChunk(fu.chunks.shift());
},
sendToServer: function(chunk, hash, callback) {
setTimeout(function() {
$('.pb').width((fu.chunkNo / fu.totalChunks * 100).toFixed(1) + '%');
$('.sent').text((fu.chunkNo*fu.chunkSize/1024/1024).toFixed(1) + 'MB / ' + (fu.file.size/1024/1024) .toFixed(1) + 'MB');
callback();
}, 200); // simulate server call and a short timeout
},
getHash: function(blob, callback) {
reader.onloadend = function(e) {
var hash = 'hash_' + fu.chunkNo.toString() + '_' + e.target.result.byteLength.toString(); // dummy hashing
callback(hash);
};
reader.readAsArrayBuffer(blob);
},
processChunk: function(chunk) {
if (chunk) {
fu.chunkNo++;
fu.getHash(chunk, function(hash) {
fu.sendToServer(chunk, hash, function() {
fu.processChunk(fu.chunks.shift());
});
});
}
}
}
$(document).ready(function() {
var input = $("body #fu");
input.get(0).addEventListener('change', fu.select, false);
});