最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arraybuffer - javascript readAsArrayBuffer returns empty Array Buffer - Stack Overflow

programmeradmin4浏览0评论

I am trying to read a local file using the FileReader readAsArrayBuffer property. The read is success and in the "onload" callback, I see the Array Buffer object in reader.result. But the Array Buffer is just empty. The length is set, but not the data. How do I get this data?

Here is my code

<!DOCTYPE html>
<html>

<body>
    <input type="file" id="file" />
</body>

<script>
    function handleFileSelect(evt) {

        var files = evt.target.files; // FileList object

        var selFile = files[0];
        var reader = new FileReader();
        reader.onload = function(e) {
            console.log(e.target.result);
        };

        reader.onerror = function(e) {
            console.log(e);
        };
        reader.readAsArrayBuffer(selFile);
    }


    document.getElementById('file').addEventListener('change', handleFileSelect, false);
</script>

</html>

the console output for reader.result

e.target.result
ArrayBuffer {}
e.target.result.byteLength
25312

Can anyone tell me how to get this data? is there some security issue? There is no error, the onerror is not executed.

From comments: Can you please let me know how to access the buffer contents? I am actually trying to play an audio file using AudioContext... For that I would need the buffer data...

I am trying to read a local file using the FileReader readAsArrayBuffer property. The read is success and in the "onload" callback, I see the Array Buffer object in reader.result. But the Array Buffer is just empty. The length is set, but not the data. How do I get this data?

Here is my code

<!DOCTYPE html>
<html>

<body>
    <input type="file" id="file" />
</body>

<script>
    function handleFileSelect(evt) {

        var files = evt.target.files; // FileList object

        var selFile = files[0];
        var reader = new FileReader();
        reader.onload = function(e) {
            console.log(e.target.result);
        };

        reader.onerror = function(e) {
            console.log(e);
        };
        reader.readAsArrayBuffer(selFile);
    }


    document.getElementById('file').addEventListener('change', handleFileSelect, false);
</script>

</html>

the console output for reader.result

e.target.result
ArrayBuffer {}
e.target.result.byteLength
25312

Can anyone tell me how to get this data? is there some security issue? There is no error, the onerror is not executed.

From comments: Can you please let me know how to access the buffer contents? I am actually trying to play an audio file using AudioContext... For that I would need the buffer data...

Share Improve this question edited Jun 6, 2014 at 7:34 nmaier 33.2k5 gold badges65 silver badges79 bronze badges asked Jun 5, 2014 at 10:00 Anand NAnand N 3901 gold badge4 silver badges12 bronze badges 4
  • 1 Why do you think the buffer is empty? Your code does not actually access/inspect the buffer contents at all. Maybe you're confused by the console.log output? console.log() will not print the contents of the buffer. – nmaier Commented Jun 5, 2014 at 10:04
  • Thanks nmaier, I thought the same...but I don't know how to access the buffer contents... Can you please let me know how to access the buffer contents? I am actually trying to play an audio file using AudioContext... For that I would need the buffer data... Many thanks for your help – Anand N Commented Jun 6, 2014 at 6:55
  • 1 You're using the onload event instead of the onloadend event. Your code will work if you replace the onload event by onloadend. See: developer.mozilla.org/en-US/docs/Web/API/FileReader – seb Commented Jun 17, 2014 at 7:00
  • @seb it was not the issue. The file that I was using was corrupted... Please check my replies to nmaier below – Anand N Commented Jun 18, 2014 at 7:37
Add a comment  | 

2 Answers 2

Reset to default 8

Here is how to read array buffer and convert it into binary string,

function onfilechange(evt) {
var reader = new FileReader(); 
reader.onload = function(evt) {
  var chars  = new Uint8Array(evt.target.result);
  var CHUNK_SIZE = 0x8000; 
  var index = 0;
  var length = chars.length;
  var result = '';
  var slice;
  while (index < length) {
    slice = chars.subarray(index, Math.min(index + CHUNK_SIZE, length)); 
    result += String.fromCharCode.apply(null, slice);
    index += CHUNK_SIZE;
  }
  // Here you have file content as Binary String in result var
};
reader.readAsArrayBuffer(evt.target.files[0]);
}

If you try to print ArrayBuffer via console.log you always get empty object {}

Well, playing a sound using the AudioContext stuff isn't actually that hard.

  1. Set up the context.
  2. Load any data into the buffer (e.g. FileReader for local files, XHR for remote stuff).
  3. Setup a new source, and start it.

All in all, something like this:

var context = new(window.AudioContext || window.webkitAudioContext)();

function playsound(raw) {
    console.log("now playing a sound, that starts with", new Uint8Array(raw.slice(0, 10)));
    context.decodeAudioData(raw, function (buffer) {
        if (!buffer) {
            console.error("failed to decode:", "buffer null");
            return;
        }
        var source = context.createBufferSource();
        source.buffer = buffer;
        source.connect(context.destination);
        source.start(0);
        console.log("started...");
    }, function (error) {
        console.error("failed to decode:", error);
    });
}

function onfilechange(then, evt) {
    var reader = new FileReader();
    reader.onload = function (e) {
        console.log(e);
        then(e.target.result);
    };
    reader.onerror = function (e) {
        console.error(e);
    };
    reader.readAsArrayBuffer(evt.target.files[0]);
}


document.getElementById('file')
  .addEventListener('change', onfilechange.bind(null, playsound), false);

See this live in a jsfiddle, which works for me in Firefox and Chrome.

I threw in a console.log(new Uint8Array()) for good measure, as browser will usually log the contents directly (if the buffer isn't huge). For other stuff that you can do with ArrayBuffers, see e.g. the corresponding MDN documentation.

发布评论

评论列表(0)

  1. 暂无评论