2016-12-08 7 views
11

मैं एक ऐसे फ़ंक्शन पर काम कर रहा हूं जो किसी तृतीय पक्ष API का उपयोग कर रिमोट सर्वर पर डेटा लिख ​​देगा। स्टैक ओवरफ़्लो पर कुछ मदद के माध्यम से मैं इसे पूरा करने में सक्षम था, जहां यह अब अपेक्षित काम कर रहा है। समस्या यह है कि मुझे केवल 16kb खंड लिखने के लिए ही मिल सकता है क्योंकि मुझे pos को अग्रिम बाइट्स के लिए लिखा जाना चाहिए।अपलोड लूप के दौरान बाइट स्थिति प्राप्त करें

प्रारंभिक लेखन आसानी से 0 से शुरू होता है। हालांकि, इसके साथ मेरी अपरिचितता के कारण, मुझे यकीन नहीं है कि अगले pos केवल 16 या क्या होना चाहिए। यदि यह मदद करता है, तो एपीआई कॉल writeFileChunk() 3 पैरामीटर, फ़ाइलपैथ (स्ट्र), pos (int64), और डेटा (बेस 64 एन्कोडेड स्ट्रिंग) लेता है।

var chunk = new Uint8Array(buffer, count++ * chunkSize, segSize); 

हालांकि, इस मामले में यह अग्रिम:

reader.onload = function(evt) 
    { 
     // Get SERVER_ID from URL 
     var server_id = getUrlParameter('id'); 

     $("#upload_status").text('Uploading File...'); 
     $("#upload_progress").progressbar('value', 0); 

     var chunkSize = 16<<10; 
     var buffer = evt.target.result; 
     var fileSize = buffer.byteLength; 
     var segments = Math.ceil(fileSize/chunkSize); // How many segments do we need to divide into for upload 
     var count = 0; 

     // start the file upload 
     (function upload() 
     { 
      var segSize = Math.min(chunkSize, fileSize - count * chunkSize); 

      if (segSize > 0) 
      { 
       $("#upload_progress").progressbar('value', (count/segments)); 

       var chunk = new Uint8Array(buffer, count++ * chunkSize, segSize); // get a chunk 
       var chunkEncoded = btoa(String.fromCharCode.apply(null, chunk)); 

       // Send Chunk data to server 
       $.ajax({ 
        type: "POST", 
        url: "filemanagerHandler.php", 
        data: { 'action': 'writeFileChunk', 'server_id': server_id, 'filepath': filepath, 'pos': 0, 'chunk': chunkEncoded }, 
        dataType: 'json', 
        success: function(data) 
        { 
         console.log(data); 
         setTimeout(upload, 100); 
        }, 
        error: function(XMLHttpRequest, textStatus, errorThrown) 
        { 
         alert("Status: " + textStatus); alert("Error: " + errorThrown); alert("Message: " + XMLHttpRequest.responseText); 
        } 
       }); 
      } 
      else 
      { 
       $("#upload_status").text('Finished!'); 
       $("#upload_progress").progressbar('value', 100); 

       getDirectoryListing(curDirectory); 
      } 
     })() 
    }; 
+1

क्या है कि 3 पार्टी एपीआई है, और प्रलेखन इस का उल्लेख नहीं है में इस उदाहरण देख सकते हैं? // यह मानने के लिए कि यह वास्तव में केवल बाइट स्थिति पर्याप्त अनुमान लग सकता है - तो जब आपने कोशिश की तो आपको क्या परिणाम मिले? – CBroe

+0

यदि यह तृतीय पक्ष एपीआई केवल बेस 64 अपलोड की अनुमति देता है तो मैं इसका उपयोग नहीं करता ... – Endless

उत्तर

9

क्लाइंट की तरफ फ़ाइल के लिए वर्तमान स्थिति इस लाइन, या पूर्व वृद्धिशील कदम पर अधिक विशेष रूप से दूसरा तर्क द्वारा प्रतिनिधित्व किया जाएगा (count++) इससे पहले कि आप पुन: उपयोग कर सकते हैं, इसलिए यदि आप वास्तविक स्थिति की जरूरत है (नीचे pos के रूप में) तो आप बस में लाइन दोबारा लिख ​​कर यह निकाल सकते हैं:

var pos = count++ * chunkSize; // here chunkSize = 16kb 
var chunk = new Uint8Array(buffer, pos, segSize); 

यहां प्रत्येक स्थिति अपडेट 16kb बढ़ जाएगा क्योंकि यह हिस्सा आकार है। प्रगति के लिए इसकी गणना pos/fileSize * 100 है। यह निश्चित रूप से unencoded बफर आकार का उपयोग कर मानते हैं।

एकमात्र विशेष मामला आखिरी हिस्सा है, लेकिन जब स्थिति पढ़ने के लिए कोई और भाग नहीं छोड़ा जाता है तो फ़ाइल लंबाई (fileSize) के बराबर होना चाहिए, इसलिए यह बहुत सीधी-आगे होना चाहिए।

जब AJAX कॉल वापस लौटाता है तो सर्वर को एक ही स्थिति होनी चाहिए जब तक कुछ गलत न हो (कनेक्शन, पहुंच परिवर्तन, डिस्क पूर्ण आदि लिखें)।

2

आप फ़ाइलों को पढ़ने और इसे अपने दूरस्थ सर्वर पर भेजने के लिए फ़ाइलreader API का उपयोग कर सकते हैं।

एचटीएमएल

<input type="file" id="files" name="file" /> Read bytes: 
<span class="readBytesButtons"> 
    <button>Read entire file in chuncks</button> 
</span> 

जावास्क्रिप्ट

// Post data to your server. 
    function postChunk(obj) { 
    var url = "https://your.remote.server"; 
    return new Promise(function(resolve, reject) { 
     var xhr = new XMLHttpRequest(); 
     xhr.open('post', url, true); 
     xhr.responseType = 'json'; 
     xhr.onload = function() { 
      var status = xhr.status; 
      if (status == 200) { 
       resolve(xhr.response); 
      } else { 
       reject(status); 
      } 
     }; 
     var params = ""; 
     // check that obj has the proper keys and create the url parameters 
      if (obj.hasOwnProperty(action) && obj.hasOwnProperty(server_id) && obj.hasOwnProperty(filepath) && obj.hasOwnProperty(pos) && obj.hasOwnProperty(chunk)) { 
      params += "action="+obj[action]+"&server_id="+obj[server_id]+"&filepath="+obj[filepath]+"&pos="+obj[pos]+"&chunk="+obj[chunk]; 
      } 
     if(params.length>0) { 
     xhr.send(params); 
     } else { 
     alert('Error'); 
     }  
    }); 
    } 
// add chunk to "obj" object and post it to server 
function addChunk(reader,obj,divID) { 
    reader.onloadend = function(evt) { 
     if (evt.target.readyState == FileReader.DONE) { // DONE == 2 
     obj.chunk = evt.target.result; 
     console.log(obj); 
      document.getElementById(divID).textContent += 
      ['Sending bytes: ', obj.pos*16000, ' - ', ((obj.pos*16000)+(obj.pos+1)*obj.chunk.length), 
      '\n'].join(''); 
     // post data to server 
     postChunk(obj).then(function(data) { 
      if(data!=="" && data!==null && typeof data!=="undefined") { 
      // chunk was sent successfully 
      document.getElementById(divID).textContent += 
      ['Sent bytes: ', obj.pos*16000, ' - ', ((obj.pos*16000)+(obj.pos+1)*obj.chunk.length),'\n'].join(''); 
      } else { 
      alert('Error! Empty response'); 
      } 
     }, function(status) { 
      alert('Resolve Error'); 
     }); 
     } 
    }; 
} 
// read and send Chunk 
function readChunk() { 
    var files = document.getElementById('files').files; 
    if (!files.length) { 
     alert('Please select a file!'); 
     return; 
    } 
    var file = files[0]; 
    var size = parseInt(file.size); 
    var chunkSize = 16000; 
    var chunks = Math.ceil(size/chunkSize); 
    var start,stop = 0; 
    var blob = []; 
    for(i=0;i<chunks;i++) { 
    start = i*chunkSize; 
    stop = (i+1)*chunkSize-1; 
    if(i==(chunks-1)) { 
    stop = size; 
    } 
    var reader = new FileReader(); 
    blob = file.slice(start, stop); 
    reader.readAsBinaryString(blob); 
    var obj = {action: 'writeFileChunk', server_id: 'sid', filepath: 'path', pos: i, chunk: ""}; 
    var div = document.createElement('div'); 
    div.id = "bytes"+i; 
    document.body.appendChild(div); 
    addChunk(reader,obj,div.id);  
    } 
} 
// Check for the various File API support. 
if (window.File && window.FileReader && window.FileList && window.Blob) { 
    console.log(' Great success! All the File APIs are supported.'); 
} else { 
    alert('The File APIs are not fully supported in this browser.'); 
} 
    document.querySelector('.readBytesButtons').addEventListener('click', function(evt) { 
    if (evt.target.tagName.toLowerCase() == 'button') { 
     readChunk(); 
    } 
    }, false); 

आप इस Fiddle

संबंधित मुद्दे