2016-09-04 6 views
2

Я пытаюсь настроить загрузку файла через отдых для больших файлов. Функция ниже заботится о chunking, но мне нужно уметь распознавать последний фрагмент, потому что мой вызов отдыха меняется на /finishUpload(), чтобы зафиксировать сохранение.Определение последнего фрагмента файла

Прямо сейчас я могу только выяснить, когда blob пуст, но я не могу понять, как определить последнюю итерацию до того, как blob пуст.

Это сценарий, который я использую ниже, чтобы проанализировать мои файлы.

export default function parseFile(file, options) { 
    var opts  = typeof options === 'undefined' ? {} : options; 
    var fileSize = file.size; 
    var chunkSize = typeof opts['chunk_size'] === 'undefined' ? 64 * 1024 : parseInt(opts['chunk_size']); 
    var binary  = typeof opts['binary'] === 'undefined' ? false : opts['binary'] == true; 
    var offset  = 0; 
    var self  = this; // we need a reference to the current object 
    var readBlock = null; 
    var chunkReadCallback = typeof opts['chunk_read_callback'] === 'function' ? opts['chunk_read_callback'] : function() {}; 
    var chunkErrorCallback = typeof opts['error_callback'] === 'function' ? opts['error_callback'] : function() {}; 
    var success = typeof opts['success'] === 'function' ? opts['success'] : function() {}; 

    var onLoadHandler = function(evt) { 
    if (evt.target.result == "") { 
     console.log('Chunk empty, call finish'); 
     success(file); 
     return; 
    } 

    if (evt.target.error == null) { 
     chunkReadCallback(evt.target.result, offset).then(function() { 
     offset += evt.target.result.length; 
     readBlock(offset, chunkSize, file); 
     }); 
    } else { 
     chunkErrorCallback(evt.target.error); 
     return; 
    } 
    if (offset >= fileSize) { 
     success(file); 
     return; 
    } 
    } 

    readBlock = function(_offset, _chunkSize, _file) { 
    var r = new FileReader(); 
    var blob = _file.slice(_offset, _chunkSize + _offset); 
    console.log("blob size:", blob.size, "offset:", _offset, "C+S:",_chunkSize + _offset) 
    r.onload = onLoadHandler; 

    if (binary) { 
     r.readAsArrayBuffer(blob); 
    } else { 
     r.readAsText(blob); 
    } 
    } 
    readBlock(offset, chunkSize, file); 
} 

Codepen

+0

Если вы знаете размер файла (вы делаете, используйте 'blob.size') и размер последнего куска, то вы можете сначала прочитать последнюю порцию, чтобы получить нужную информацию а затем продолжайте то, что вы сейчас делаете. –

ответ

0

Почему бы не полагаться на размер_файла, т.е. проверить состояние _chunkSize + _offset >= fileSize?

+0

Не знаю, почему, но он все время возвращается. http://codepen.io/simkessy/pen/vXYbvW?editors=0011 – Batman

0

Вы можете использовать progress, loadend события для обработки File объект по одному байту за раз; определить переменную, где обработка должна быть приостановлена ​​или остановлена ​​в n-м байте, каждом n-м байте или любом байте во время обработки файла.

var str = "abcdefghijklmnopqrstuvwxyz"; 
 
var type = "application/octet-stream"; 
 
var data = new Blob([], { 
 
    type: type 
 
}); 
 
var filename = "file.txt"; 
 
var reader = new FileReader(); 
 
var complete = false; 
 
var beforeEnd = false; 
 
var stopAt = str.length - 1; 
 

 
function handleFile(e) { 
 
    data = new File([data.slice() 
 
        , str.slice(data.size, data.size + 1)] 
 
        , filename, { 
 
         type: type, 
 
         lastModifiedDate: new Date() 
 
      }); 
 
} 
 

 
function handleRead(e) { 
 
    if (data.size <= str.length && !complete) { 
 
    if (data.size === stopAt && !beforeEnd) { 
 
     beforeEnd = true; 
 
     var r = new FileReader(); 
 
     r.onloadend = function() {    
 
     alert(`stopAt: ${stopAt}\n` 
 
       +`data.size: ${data.size}\n` 
 
       +`result at stopAt: ${r.result[stopAt -1]}`); 
 
     reader.readAsArrayBuffer(data); 
 
     } 
 
     r.readAsText(data); 
 
    } else { 
 
     reader.readAsArrayBuffer(data) 
 
    } 
 
    } else { 
 
    console.log("complete") 
 
    } 
 
} 
 

 
function handleProgress(e) { 
 
    if (data.size <= str.length && !complete) { 
 
    var read = new FileReader(); 
 
    read.onload = function() { 
 
     if (!complete) { 
 
     console.log(read.result); 
 
     if (read.result.length === str.length) { 
 
      complete = true; 
 
      console.log(data); 
 
     } 
 
     } 
 
    } 
 
    read.readAsText(data); 
 
    } 
 
} 
 

 
reader.addEventListener("load", handleFile); 
 

 
reader.addEventListener("loadend", handleRead); 
 

 
reader.addEventListener("progress", handleProgress); 
 

 
reader.readAsArrayBuffer(data);