完全等待 FileReader 切片 blob
Wait for FileReader slice blob entirely
我正在尝试使用 FileReader API 读取文件数据,并且我阅读了很多关于相同问题的问题并尝试实施他们的解决方案,但是对于我的代码中的一些错误(也许),它继续做错误的结果。为了避免文件太大(超过 15MB)时浏览器崩溃,我决定开始使用 'slice' 方法。但问题是,由于 FileReader onload 事件是异步的,所以我得到了代码的一部分,它应该尽快准备好完整的缓冲区,但它仍然不完整。而且我不能将所有内容都放在 onload 事件中,因为它只有总缓冲区的一部分。这是我的代码:
function readBlob(opt_startByte, opt_stopByte)
{
var file = window.files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onload = function(evt) {
window.bits.push(CryptoJS.AES.encrypt(evt.target.result, window.password));
};
var blob = file.slice(start, stop + 1);
reader.readAsDataURL(blob);
}
function encrypt()
{
window.files = document.getElementById('encrypt-input').files;
if (!window.files.length) {
alert('Please select a file!');
return;
}
window.password = $('#key').val();
window.bits = [];
var startByte = 0;
var endByte = 0;
while(startByte <= document.querySelector('input[type=file]').files[0].size - 1)
{
endByte = startByte + 1024;
readBlob(startByte, endByte);
startByte = endByte;
if (startByte >= document.querySelector('input[type=file]').files[0].size)
{
alert('Here I want the total array length:' + window.bits.length);
}
}
alert('Here I want the total array length:' + window.bits.length);
}
正如您在上方看到的那样,我试过这个:
if (startByte >= document.querySelector('input[type=file]').files[0].size)
{
alert('Here I want the total array length:' + window.bits.length);
}
但出于某种原因,我的长度仍然为 0。使用 slice 方法时如何处理整个缓冲区?另一个次要问题是:在 onload 事件中,我调用了一个同步函数 'CryptoJS.AES.encrypt',但由于此事件是异步的,所以我希望浏览器在处理此事件的缓冲区时不会冻结。有什么方法可以避免在处理文件时冻结浏览器?
发生这种情况的原因是 reader.readAsDataURL()
是异步的。您必须将回调传递给 readBlob
,它在完成时被调用:
function readBlob(opt_startByte, opt_stopByte, done) {
...
reader.onload = function(evt) {
window.bits.push(CryptoJS.AES.encrypt(evt.target.result, window.password));
done();
};
...
}
function encrypt() {
...
var startByte = 0;
var endByte = 0;
var callback = function(){
alert('Here I want the total array length:' + window.bits.length);
};
while(startByte <= document.querySelector('input[type=file]').files[0].size - 1) {
endByte = startByte + 1024;
(function(startByte, endByte, newCallback){
callback = function(){
readBlob(startByte, endByte, newCallback);
};
})(startByte, endByte, callback);
startByte = endByte;
}
callback(); // run the chain
}
没有其他明智的方法,因为 JavaScript 没有 sleep
功能。
看来您需要这样做 "sync way"。您可以在此处找到文档 -> http://www.w3.org/TR/FileAPI/#FileReaderSync。
我还发现了这个库 - FileReader.js (http://bgrins.github.io/filereader.js/) 它不仅让你在使用 FileReader 时更轻松,而且已经内置了使用同步方法同步读取文件的选项文件。
很抱歉现在无法 post 一些示例代码!无论如何,希望它有所帮助!
我正在尝试使用 FileReader API 读取文件数据,并且我阅读了很多关于相同问题的问题并尝试实施他们的解决方案,但是对于我的代码中的一些错误(也许),它继续做错误的结果。为了避免文件太大(超过 15MB)时浏览器崩溃,我决定开始使用 'slice' 方法。但问题是,由于 FileReader onload 事件是异步的,所以我得到了代码的一部分,它应该尽快准备好完整的缓冲区,但它仍然不完整。而且我不能将所有内容都放在 onload 事件中,因为它只有总缓冲区的一部分。这是我的代码:
function readBlob(opt_startByte, opt_stopByte)
{
var file = window.files[0];
var start = parseInt(opt_startByte) || 0;
var stop = parseInt(opt_stopByte) || file.size - 1;
var reader = new FileReader();
// If we use onloadend, we need to check the readyState.
reader.onload = function(evt) {
window.bits.push(CryptoJS.AES.encrypt(evt.target.result, window.password));
};
var blob = file.slice(start, stop + 1);
reader.readAsDataURL(blob);
}
function encrypt()
{
window.files = document.getElementById('encrypt-input').files;
if (!window.files.length) {
alert('Please select a file!');
return;
}
window.password = $('#key').val();
window.bits = [];
var startByte = 0;
var endByte = 0;
while(startByte <= document.querySelector('input[type=file]').files[0].size - 1)
{
endByte = startByte + 1024;
readBlob(startByte, endByte);
startByte = endByte;
if (startByte >= document.querySelector('input[type=file]').files[0].size)
{
alert('Here I want the total array length:' + window.bits.length);
}
}
alert('Here I want the total array length:' + window.bits.length);
}
正如您在上方看到的那样,我试过这个:
if (startByte >= document.querySelector('input[type=file]').files[0].size)
{
alert('Here I want the total array length:' + window.bits.length);
}
但出于某种原因,我的长度仍然为 0。使用 slice 方法时如何处理整个缓冲区?另一个次要问题是:在 onload 事件中,我调用了一个同步函数 'CryptoJS.AES.encrypt',但由于此事件是异步的,所以我希望浏览器在处理此事件的缓冲区时不会冻结。有什么方法可以避免在处理文件时冻结浏览器?
发生这种情况的原因是 reader.readAsDataURL()
是异步的。您必须将回调传递给 readBlob
,它在完成时被调用:
function readBlob(opt_startByte, opt_stopByte, done) {
...
reader.onload = function(evt) {
window.bits.push(CryptoJS.AES.encrypt(evt.target.result, window.password));
done();
};
...
}
function encrypt() {
...
var startByte = 0;
var endByte = 0;
var callback = function(){
alert('Here I want the total array length:' + window.bits.length);
};
while(startByte <= document.querySelector('input[type=file]').files[0].size - 1) {
endByte = startByte + 1024;
(function(startByte, endByte, newCallback){
callback = function(){
readBlob(startByte, endByte, newCallback);
};
})(startByte, endByte, callback);
startByte = endByte;
}
callback(); // run the chain
}
没有其他明智的方法,因为 JavaScript 没有 sleep
功能。
看来您需要这样做 "sync way"。您可以在此处找到文档 -> http://www.w3.org/TR/FileAPI/#FileReaderSync。 我还发现了这个库 - FileReader.js (http://bgrins.github.io/filereader.js/) 它不仅让你在使用 FileReader 时更轻松,而且已经内置了使用同步方法同步读取文件的选项文件。 很抱歉现在无法 post 一些示例代码!无论如何,希望它有所帮助!