कैसे बूँद से ArrayBuffer जाने के लिए


111

मैं Blobs का अध्ययन कर रहा था, और मैंने देखा कि जब आपके पास एक ArrayBuffer होता है, तो आप इसे आसानी से Blob में बदल सकते हैं:

var dataView = new DataView(arrayBuffer);
var blob = new Blob([dataView], { type: mimeString });

मेरे पास अब जो सवाल है, क्या यह एक बूँद से एक ArrayBuffer तक जाना संभव है?


2
बूँदें मूल जेएस प्रारूप में नहीं हैं। वे डेटा के संदर्भ की तरह हैं, लेकिन वास्तविक डेटा के नहीं। डेटा Blobसीधे नहीं पढ़ा जा सकता है लेकिन यह कुछ एपीआई के साथ किया जा सकता है।
त्रियुल

जवाबों:


39

Responseएपीआई की खपत एक (अपरिवर्तनीय) Blobजहाँ से डेटा कई मायनों में प्राप्त किया जा सकता है। ओपी केवल के लिए कहा ArrayBuffer, और यहाँ इसके बारे में एक प्रदर्शन है।

var blob = GetABlobSomehow();

// NOTE: you will need to wrap this up in a async block first.
/* Use the await keyword to wait for the Promise to resolve */
await new Response(blob).arrayBuffer();   //=> <ArrayBuffer>

वैकल्पिक रूप से आप इसका उपयोग कर सकते हैं:

new Response(blob).arrayBuffer()
.then(/* <function> */);

नोट: यह API पुराने ( प्राचीन ) ब्राउज़रों के साथ संगत नहीं है इसलिए ब्राउज़र संगतता तालिका पर नज़र डालें ताकि वह सुरक्षित हो;)


1
यह शीर्ष उत्तर IMO होना चाहिए।
कैमरन मार्टिन

const arrayBuffer = new response (blob) .arrayBuffer () का इंतजार करें;
R.Cha

1
@ R.Cha फिक्स के लिए धन्यवाद। मैंने देखा कि नहीं!
त्रियुल

2
चालाक चाल और न साथ भ्रमित होने की Blob.arrayBuffer()जो वास्तव में भी 2020 में काफी खराब संगतता है, caniuse.com/#feat=mdn-api_blob_arraybuffer या developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer
jpschroeder

इसका प्रदर्शन क्या है? क्या यह बूँद में डेटा की प्रतिलिपि बनाता है या सिर्फ इसका एक दृश्य लौटाता है?
गैरीओ

141

आप एक FileReaderके Blobरूप में पढ़ने के लिए उपयोग कर सकते हैं ArrayBuffer

यहाँ एक छोटा उदाहरण दिया गया है:

var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function(event) {
    arrayBuffer = event.target.result;
};
fileReader.readAsArrayBuffer(blob);

यहाँ एक लंबा उदाहरण है:

// ArrayBuffer -> Blob
var uint8Array  = new Uint8Array([1, 2, 3]);
var arrayBuffer = uint8Array.buffer;
var blob        = new Blob([arrayBuffer]);

// Blob -> ArrayBuffer
var uint8ArrayNew  = null;
var arrayBufferNew = null;
var fileReader     = new FileReader();
fileReader.onload  = function(event) {
    arrayBufferNew = event.target.result;
    uint8ArrayNew  = new Uint8Array(arrayBufferNew);

    // warn if read values are not the same as the original values
    // arrayEqual from: http://stackoverflow.com/questions/3115982/how-to-check-javascript-array-equals
    function arrayEqual(a, b) { return !(a<b || b<a); };
    if (arrayBufferNew.byteLength !== arrayBuffer.byteLength) // should be 3
        console.warn("ArrayBuffer byteLength does not match");
    if (arrayEqual(uint8ArrayNew, uint8Array) !== true) // should be [1,2,3]
        console.warn("Uint8Array does not match");
};
fileReader.readAsArrayBuffer(blob);
fileReader.result; // also accessible this way once the blob has been read

क्रोम 27-69, फ़ायरफ़ॉक्स 20-60 और सफारी 6-11 के कंसोल में इसका परीक्षण किया गया था।

यहाँ एक लाइव प्रदर्शन भी है, जिसे आप इसके साथ खेल सकते हैं: https://jsfiddle.net/potatosalad/FbaM6/

अपडेट 2018-06-23:event.target.result बनाम के बारे में टिप के लिए क्लॉस क्लेन का धन्यवादthis.result

संदर्भ:


23
यह बहुत सारे कोड की तरह प्रतीत नहीं होता है .. कुछ के लिए जो सरल होना चाहिए?
हेन्ले चिउ

3
@HenleyChiu मैंने कोड का संक्षिप्त संस्करण शामिल करने के लिए उत्तर को संपादित किया। लंबा उदाहरण पूरी तरह से आत्म-निहित होने का इरादा रखता है (दिखाता है कि कैसे ArrayBuffer, Blob, और फिर से वापस बनाने के लिए)। मैं वेब वर्कर और FileReaderSync का उपयोग किए बिना ब्लॉब पढ़ने के लिए एक तुल्यकालिक तरीका खोजने में सक्षम नहीं हूं
पोटाटोसालड

1
कुछ लोग वास्तव में यह साबित करना चाहते हैं कि कॉलबैक नरक मौजूद है। यह लार्स ब्लॉब्स के लिए समझ में आता है, लेकिन सामान्य उपयोग के मामलों के लिए जावास्क्रिप्ट को एक सिंक विधि प्रदान करनी चाहिए।
lama12345

यह बहुत उपयोगी था
जिमी ओबोनियो अबोर

@ अनुज आपने गलत किया है। यह उल्लेख नहीं करना चाहिए this<EventTarget>.resultउसे ठीक करना चाहिए!
त्रिपुसल

17

बस श्री @potatosalad उत्तर को पूरक करने के लिए।

आपको वास्तव में ऑनलोड कॉलबैक पर परिणाम प्राप्त करने के लिए फ़ंक्शन स्कोप तक पहुंचने की आवश्यकता नहीं है , आप ईवेंट पैरामीटर पर निम्न रूप से कर सकते हैं :

var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function(event) {
    arrayBuffer = event.target.result;
};
fileReader.readAsArrayBuffer(blob);

यह बेहतर क्यों है? क्योंकि तब हम संदर्भ को खोए बिना तीर फ़ंक्शन का उपयोग कर सकते हैं

var fileReader = new FileReader();
fileReader.onload = (event) => {
    this.externalScopeVariable = event.target.result;
};
fileReader.readAsArrayBuffer(blob);

15

या आप भ्रूण एपीआई का उपयोग कर सकते हैं

fetch(URL.createObjectURL(myBlob)).then(res => res.arrayBuffer())

मुझे नहीं पता कि प्रदर्शन अंतर क्या है, और यह आपके नेटवर्क टैब पर DevTools में भी दिखाई देगा।


17
या सिर्फnew Response(blob).arrayBuffer()
एंडलेस

4

नहीं है अब (क्रोम 76+ और एफएफ 69+) एक Blob.prototype.arrayBuffer () विधि है जो एक वादा एक ArrayBuffer ब्लॉब के डेटा का प्रतिनिधित्व करने के साथ हल करने वापस आ जाएगी।

(async () => {
  const blob = new Blob(['hello']);
  const buf = await blob.arrayBuffer();
  console.log( buf.byteLength ); // 5
})();


2
दुर्भाग्य से वर्तमान में सफारी (अभी तक) में काम नहीं करता है
हेरज़ेटाके
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.