2014-10-15 17 views
9

Trong ứng dụng Cordova của tôi, tôi đang tải xuống các tệp tùy ý như hình ảnh hoặc tệp video. Điều này được thực hiện với plugin chuyển tập tin Cordova và tiêu đề "Phạm vi", bởi vì tôi cần tải xuống các tệp trong các phần.Hợp nhất nhiều phần của một tệp trong Cordova

Vấn đề của tôi là, tôi muốn hợp nhất lại một số nhỏ "Byte" -Files trở lại với nhau thành tệp gốc mà họ từng sử dụng tệp đó. Mỗi lần tôi cố gắng đọc các phần kết quả như binaryString thông qua FileReader và viết chúng lại với nhau trong một tệp mới, tệp đó kết thúc lớn hơn rất nhiều so với các phần của tệp gốc altogther và tệp kết quả là không sử dụng được.

Mọi trợ giúp đều được đánh giá cao.

Đây là mã của tôi cho đến bây giờ (dài và xấu xí): Mã

document.addEventListener('deviceready', deviceready, false); 

var App; 

var finishedFileUrl = ""; 

var async = { 
    sequence: function(items, callback) {  
     var def = $.Deferred(), 
     deferrers = [$.Deferred()]; 

     for(var i = 0; i < items.length; i++) { 
      (function (n) {  
       deferrers[n + 1] = $.Deferred(); 
       deferrers[n].always(function() { 
        callback(items[n], deferrers[n + 1]); 
       }); 
      })(i); 
     } 
     deferrers[items.length].always(function() { 
      def.resolve(); 
     });   
     deferrers[0].resolve(); 

     return def.promise(); 
    } 
} 

var aSmallImageArray = [ 
'' // Put URL to JPG accessible with Range Header Request here 
]; 

var aByteSizeImageArray = []; 

function formatDownloadArray(fileSize) { 
    for(var j = 1000; j <= fileSize; j += 1000) { 
     aByteSizeImageArray.push(j); 
    } 
    aByteSizeImageArray.push(j); 
} 

function deviceready() { 
    console.log('dv ready'); 

    function registerHandlers() { 
     App = new DownloadApp(); 
     formatDownloadArray(XXXXX);  // XXXXX should be size of JPG in bytes 
     document.getElementById("startDl").onclick = function() { 
      var that = this; 
      console.log("load button clicked"); 
      var folderName = "testimagefolder"; 

      // sequence call 
      async.sequence(aByteSizeImageArray, function(currentBytes, iter) { 
       var filePath = aSmallImageArray[0]; 
       var fileName = aSmallImageArray[0].substr(52,99) + currentBytes; 
       console.log(filePath); 
       console.log(fileName); 
       console.log("Starting with: " + fileName); 
       var uri = encodeURI(filePath); 
       var folderName = "testimagefolder"; 
       document.getElementById("statusPlace").innerHTML = "<br/>Loading: " + uri; 
       App.load(currentBytes, uri, folderName, fileName, 
        function progress (percentage) { 
         document.getElementById("statusPlace").innerHTML = "<br/>" + percentage + "%"; 
        }, 
        function success (entry) { 
         console.log("Entry: " + entry); 
         document.getElementById("statusPlace").innerHTML = "<br/>Image saved to: " + App.filedir; 
         console.log("DownloadApp.filedir: " + App.filedir); 
         iter.resolve(); 
        }, 
        function error() { 
         document.getElementById("statusPlace").innerHTML = "<br/>Failed load image: " + uri; 
         iter.resolve(); 
        } 
       );    
      }).then(function afterAsync() { 
       console.log("ASYNC DONE"); 
       var ohNoItFailed = function ohNoItFailed (exeperro) { 
        console.log(exeperro); 
       } 
       // now we merge the fileparts into one file to show it 
       window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (FileSystem) { 
        FileSystem.root.getDirectory(folderName, {create: true, exclusive: false}, function itSuccessed (Directory) { 
         Directory.getFile(aSmallImageArray[0].substr(52,99), {create: true, exclusive: false}, function itSuccessedAgain (fileEntry) { 
          finishedFileUrl = fileEntry.toURL(); 
          var directoryReader = Directory.createReader(); 
          var allFiles = directoryReader.readEntries(function succesReadDir (fileEntries) { 
           async.sequence(fileEntries, function(currentFile, iterThis) { 
            currentFile.file(function (theActualFile) { 
             var myFileReader = new FileReader(); 
             myFileReader.onload = function (content) { 
              console.log('FileReader onload event fired!'); 
              console.log('File Content should be: ' + content.target.result); 
              fileEntry.createWriter(
              function mergeImage (writer) { 
               writer.onwrite = function (evnt) { 
                console.log("Writing successful!"); 
                iterThis.resolve(); 
               } 
               writer.seek(writer.length); 
               writer.write(content.target.result); 
              }, ohNoItFailed); 
             }; 
             myFileReader.readAsBinaryString(theActualFile); 
            }, ohNoItFailed); 
           }).then(function afterAsyncTwo() { 
            console.log("NOW THE IMAGE SHOULD BE TAKEN FROM THIS PATH: " + finishedFileUrl); 

            //window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (FileSystem) { 
             //FileSystem.root.getDirectory(folderName, {create: true, exclusive: false}, function itSuccessed (Directory) { 
              //Directory.getFile(aSmallImageArray[0].substr(52,99), {create: true, exclusive: false}, function  itSuccessedAgain (fileEntry) {  
               //fileEntry.createWriter( 

             document.getElementById("image_here").src = finishedFileUrl;  
           });  
          }, ohNoItFailed);        
         }, ohNoItFailed);  
        }, ohNoItFailed);  
       }, ohNoItFailed);      
      });  
     };  
    }  
    registerHandlers();  
}  

var DownloadApp = function() {} 

DownloadApp.prototype = { 
    filedir: "", 
    load: function(currentBytes, uri, folderName, fileName, progress, success, fail) { 
     var that = this; 
     that.progress = progress; 
     that.success = success; 
     that.fail = fail; 
     filePath = ""; 

     that.getFilesystem(
       function(fileSystem) { 
        console.log("GotFS"); 
        that.getFolder(fileSystem, folderName, function(folder) { 
         filePath = folder.toURL() + fileName; 
         console.log("FILEPATH: " + filePath); 
         console.log("URI: " + uri); 
         that.transferFile(currentBytes, uri, filePath, progress, success, fail); 
        }, function(error) { 
         console.log("Failed to get folder: " + error.code); 
         typeof that.fail === 'function' && that.fail(error); 
        }); 
       }, 
       function(error) { 
        console.log("Failed to get filesystem: " + error.code); 
        typeof that.fail === 'function' && that.fail(error); 
       } 
     ); 
    }, 

    getFilesystem: function (success, fail) { 
     window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; 
     window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, success, fail); 
    }, 

    getFolder: function (fileSystem, folderName, success, fail) { 
     fileSystem.root.getDirectory(folderName, {create: true, exclusive: false}, success, fail) 
    }, 

    transferFile: function (currentBytes, uri, filePath, progress, success, fail) { 
     var that = this; 
     that.progress = progress; 
     that.success = success; 
     that.fail = fail; 
     console.log("here we go"); 
     console.log("filePath before Request: " + filePath); 

     var previousBytes = currentBytes - 1000; 

     var transfer = new FileTransfer(); 
     transfer.onprogress = function(progressEvent) { 
      if (progressEvent.lengthComputable) { 
       var perc = Math.floor(progressEvent.loaded/progressEvent.total * 100); 
       typeof that.progress === 'function' && that.progress(perc); // progression on scale 0..100 (percentage) as number 
      } else { 
      } 
     }; 

     transfer.download(
      uri, 
      filePath, 
      function success (entry) { 
       console.log("File saved to: " + entry.toURL()); 
       typeof that.success === 'function' && that.success(entry); 
      }, 
      function errorProblem(error) { 
       console.log("An error has occurred: Code = " + error.code); 
       console.log("download error source " + error.source); 
       console.log("download error target " + error.target); 
       console.log("download error code " + error.code); 
       typeof that.fail === 'function' && that.fail(error); 
      }, 
      true, 
      { 
       headers: { 
        "Range": "bytes=" + previousBytes + "-" + currentBytes 
       } 
      } 
     ); 
    } 
} 

async bởi stackoverflow người dùng: Paul Facklam -> Cảm ơn rất nhiều!

+0

Bạn có thể thêm thêm chi tiết và nhận xét mã không? Dường như bạn đang cố gắng tải 1000 byte mỗi lần, nhưng có một vài số ma thuật trong đó không rõ ràng ('1000',' 52', '99'). Nếu các phần kết quả của bạn được lắp ráp lớn hơn dự kiến, có thể bạn đã viết tệp trở lại dưới dạng ASCII/ký tự thay vì dữ liệu nhị phân không? Bạn đã quên bỏ qua các tiêu đề phản hồi chưa? (nếu có; không chắc chắn) Đề xuất: thử tải xuống tệp nhỏ-ish chỉ có một vài phần và sử dụng trình chỉnh sửa hex để so sánh các phần đã lưu với tệp gốc từ máy chủ. Heck, hãy thử với một tập tin thô. – nothingisnecessary

+0

"Số ma thuật" được sử dụng để trích xuất tên tệp từ phần tử đầu tiên trong mảng (52,99), 1000, như bạn đã giả định chính xác, tương ứng với phần 1000 byte tôi muốn tải xuống. Tôi đã thử với một tập tin nhỏ hơn và nếu tôi nhìn vào các nội dung, chúng chắc chắn không phải là nhị phân, mà là các ký tự bytecode. Tôi có thể đăng một ví dụ về một phần của tập tin đó, nếu điều đó sẽ giúp. – plocks

Trả lời

1

Sử dụng readAsArrayBuffer() thay vì readAsBinaryString() đã thực hiện thủ thuật!

Vì vậy, thay vì:

myFileReader.readAsBinaryString(theActualFile); 

tôi đã làm:

myFileReader.readAsBinaryArray(theActualFile); 

Và kết quả là các tập tin hình ảnh là sử dụng được.

1

bạn có thể tạo một đốm màu từ các đốm màu khác, giống như những đốm bạn sử dụng FileReader ngay bây giờ. (File() s là Blobs)

// put three blobs into a fourth: 
var b=new Blob([new Blob(["hello"]), new Blob([" "]), new Blob(["world"])]); 

// verify the blob has the data we expect: 
var fr=new FileReader(); 
fr.onload=function(){alert(this.result);}; 
fr.readAsBinaryString(b); // shows: "hello world" 

hương vị binaryString được sử dụng ở đây để chứng tỏ những chuỗi bậc thấp chồng lên, nhưng trường hợp blob mới thực tế nên có tất cả các orig (tùy ý) byte từ bản gốc các đốm màu, ngay cả khi chúng không bao gồm các chuỗi đơn giản ...

+0

Tôi sẽ kiểm tra điều đó. Cảm ơn. – plocks

+0

Ok, tôi đã thử nghiệm nó và nó không làm việc cho tôi. Nó vẫn không tạo ra một tệp hình ảnh có thể xem được. – plocks

+0

@DevanLoper: mà không nhìn thấy mã cập nhật của bạn, tôi không thể nói lý do tại sao nó không hoạt động, nhưng tôi đã xác minh rằng dữ liệu nhị phân có thể được cắt nhỏ và lắp ráp lại bằng cách sử dụng phương pháp trên: http://jsfiddle.net/ox0rgmvc/ 1/ – dandavis

Các vấn đề liên quan