使用Blob从ArrayBuffer构造文件

时间:2015-05-05 20:43:24

标签: google-chrome blob filereader chromium arraybuffer

我正在尝试一些HTML5 API,如FileReader,Blob等。我正在尝试将文件切成块,将每个块作为数组缓冲区读取,通过将所有分块数组缓冲区添加到一起来创建blob,然后重新构建文件。我遇到的问题是重建文件后,除了文本文件以外,大多数文件类型的文件都已损坏。知道为什么吗?以下是我到目前为止的代码。

JSFiddle Code Sample

<input type="file" id="files" name="files[]" multiple><button id="a">anaylze</button>



 document.getElementById('a').addEventListener('click', sliceFileToSend, false);
document.getElementById('files').addEventListener('change', handleFileSelect, false);
var files;
var blob = new Blob();
var filename='';

function handleFileSelect(evt) {
  files = evt.target.files; 
}

function sliceFileToSend() {
  console.log("enter sliceFileToSend function");

  if (typeof files !== 'undefined') {
    for (var j = 0, len = files.length; j < len; j++) {
      if (files[j].size > 25 * 1024 * 1024) {
        continue;
      }
      filename=files[j].name;
      alert(JSON.stringify({
        filename: files[j].name
      }));

      parseFile(files[j]);
    }
  }
}

function parseFile(file) {
  var fileSize = file.size;
  var chunkSize = 16 * 1024; // bytes
  var offset = 0;  
  var block = null;


  var foo = function(evt) {
    if (evt.target.error === null) {
      offset += evt.target.result.byteLength;
      blob = new Blob([evt.target.result,blob]); // callback for handling read chunk
    }
    else {
      console.log("Read error: " + evt.target.error);
      return;
    }
    if (offset >= fileSize) {
      console.log("Done reading file");
      alert({
        isEnded: true
      });
      saveFile(blob,filename);
      return;
    }

    block(offset, chunkSize, file);
  };

  block = function(_offset, length, _file) {
    var r = new FileReader();
    var blob = _file.slice(_offset, length + _offset);
    r.onload = foo;
    r.readAsArrayBuffer(blob);
  };

  block(offset, chunkSize, file);
}

function saveFile(blob, fileName) {
  var link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = fileName;
  link.click();
}

2 个答案:

答案 0 :(得分:1)

不要太贴近:

blob = new Blob([evt.target.result,blob])

这似乎预先每个块的数据,而你增加了每个块的偏移量。所以这些块会反过来重新组装。

答案 1 :(得分:0)

    document.getElementById('a').addEventListener('click', sliceFileToSend, false);
   document.getElementById('files').addEventListener('change', handleFileSelect, false);
        var files;


        function handleFileSelect(evt) {
          files = evt.target.files; 
        }

        function sliceFileToSend() {
          console.log("enter sliceFileToSend function");

          if (typeof files !== 'undefined') {
            for (var j = 0, len = files.length; j < len; j++) {
              if (files[j].size > 25 * 1024 * 1024) {
                continue;
              }
              parseFile(files[j]);
            }
          }
        }

        function parseFile(file) {
          var fileSize = file.size;
          var chunkSize = 16 * 1024; // bytes
          var offset = 0;  
          var block = null;
          var blob = new Blob();
          var filename=file.name;



          var foo = function(evt) {
            if (evt.target.error === null) {
              offset += evt.target.result.byteLength;
              blob = new Blob([blob,evt.target.result]); // callback for handling read chunk
            }
            else {
              console.log("Read error: " + evt.target.error);
              return;
            }
            if (offset >= fileSize) {
              console.log("Done reading file");
              alert("Done reading file");
              saveFile(blob,filename);
              offset=0;
              blob = null;
              return;
            }

            block(offset, chunkSize, file);
          };

          block = function(_offset, length, _file) {
            var r = new FileReader();
            var blob = _file.slice(_offset, length + _offset);
            r.onload = foo;
            r.readAsArrayBuffer(blob);
          };

          block(offset, chunkSize, file);
        }

        function saveFile(blob, fileName) {
          var link = document.createElement('a');
          link.href = window.URL.createObjectURL(blob);
          link.download = fileName;
          link.click();
        }