11

我正在尝试使用 FileReader readAsArrayBuffer 属性读取本地文件。读取成功,在“onload”回调中,我在 reader.result 中看到了 Array Buffer 对象。但是数组缓冲区只是空的。长度已设置,但数据未设置。我如何获得这些数据?

这是我的代码

<!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>

reader.result 的控制台输出

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

谁能告诉我如何获取这些数据?有什么安全问题吗?没有错误,onerror没有执行。

来自评论:你能告诉我如何访问缓冲区内容吗?我实际上正在尝试使用AudioContext...播放音频文件为此我需要缓冲区数据...

4

2 回答 2

8

这是读取数组缓冲区并将其转换为二进制字符串的方法,

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]);
}

如果您尝试通过 console.log 打印 ArrayBuffer,您总是会得到空对象 {}

于 2014-09-03T19:40:12.483 回答
5

好吧,使用这些东西播放声音AudioContext实际上并不难。

  1. 设置上下文。
  2. 将任何数据加载到缓冲区中(例如FileReader,对于本地文件,XHR对于远程内容)。
  3. 设置一个新的源,然后启动它。

总而言之,是这样的:

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);

在jsfiddle中看到这个,它在 Firefox 和 Chrome 中对我有用。

我投入了一个console.log(new Uint8Array())很好的措施,因为浏览器通常会直接记录内容(如果缓冲区不是很大)。对于您可以使用ArrayBuffers 进行的其他操作,请参阅例如相应的 MDN 文档

于 2014-06-06T07:33:30.250 回答