将输入=文件转换为字节数组

IT技术 javascript filereader
2021-03-21 08:11:02

我尝试将通过输入文件获得的文件转换为字节 []。我尝试使用 FileReader,但我必须错过一些东西:

var bytes = [];
var reader = new FileReader();
reader.onload = function () {
   bytes = reader.result;
};
reader.readAsArrayBuffer(myFile);

但最后,我的字节变量不满足字节数组。

我看到了这篇文章:通过输入类型 = 文件获取字节数组但它不以字节 [] 结尾,并且不推荐使用 readAsBinaryString()

我想念什么?

4个回答

面临类似的问题,这是真的,'reader.result' 并没有最终成为 'byte[]'。所以我将它转换为 Uint8Array 对象。这也不是一个完美的 'byte[]' ,所以我不得不从中创建一个 'byte[]' 。这是我对这个问题的解决方案,它对我来说效果很好。

var reader = new FileReader();
var fileByteArray = [];
reader.readAsArrayBuffer(myFile);
reader.onloadend = function (evt) {
    if (evt.target.readyState == FileReader.DONE) {
       var arrayBuffer = evt.target.result,
           array = new Uint8Array(arrayBuffer);
       for (var i = 0; i < array.length; i++) {
           fileByteArray.push(array[i]);
        }
    }
}

'fileByteArray' 就是你要找的。看到评论,似乎你也做了同样的事情,仍然想分享这个方法。

This too is not a perfect 'byte[]' 你可以解释吗?
2021-04-30 08:11:02
请花一些时间来正确缩进您的代码。在左侧有 10、15 个空列是没有意义的!
2021-05-05 08:11:02

在我看来您只是想将文件放入数组中?这些函数怎么样 - 一个可以作为文本读取,另一个作为 base64 字节字符串,如果你真的想要readAsArrayBuffer数组缓冲区输出,我也包括在内:

document.getElementById("myBtn").addEventListener("click", function() {
  uploadFile3();
}); 

var fileByteArray = [];

function uploadFile1(){
  var files = myInput.files[0];
  var reader = new FileReader();
  reader.onload = processFile(files);
  reader.readAsText(files); 
}

function uploadFile2(){
  var files = document.querySelector('input').files[0];
  var reader = new FileReader();
  reader.onload = processFile(files);
  reader.readAsDataURL(files); 
}

function uploadFile3(){
  var files = myInput.files[0];
  var reader = new FileReader();
  reader.onload = processFile(files);
  reader.readAsArrayBuffer(files); 
}

function processFile(theFile){
  return function(e) { 
    var theBytes = e.target.result; //.split('base64,')[1]; // use with uploadFile2
    fileByteArray.push(theBytes);
    document.getElementById('file').innerText = '';
    for (var i=0; i<fileByteArray.length; i++) {
        document.getElementById('file').innerText += fileByteArray[i];
    }
  }
}
<input id="myInput" type="file">    
<button id="myBtn">Try it</button>
<span id="file"></span>

这是已接受答案的修改后的,在我看来更简单的版本。此函数返回一个值为 byte[]Promise

function fileToByteArray(file) {
    return new Promise((resolve, reject) => {
        try {
            let reader = new FileReader();
            let fileByteArray = [];
            reader.readAsArrayBuffer(file);
            reader.onloadend = (evt) => {
                if (evt.target.readyState == FileReader.DONE) {
                    let arrayBuffer = evt.target.result,
                        array = new Uint8Array(arrayBuffer);
                    for (byte of array) {
                        fileByteArray.push(byte);
                    }
                }
                resolve(fileByteArray);
            }
        }
        catch (e) {
            reject(e);
        } 
    })
}

这样你就可以像这样在异步函数中简单地调用这个函数

async function getByteArray() {
    //Get file from your input element
    let myFile = document.getElementById('myFileInput').files[0];

    //Wait for the file to be converted to a byteArray
    let byteArray = await fileToByteArray(myFile);

    //Do something with the byteArray
    console.log(byteArray);
}

这在 React JS 中对我来说非常有效:

 const handleUpload = async (e) => {
    let image = e.currentTarget.files[0];
    const buffer = await image.arrayBuffer();
    let byteArray = new Int8Array(buffer);
    console.log(byteArray)
    formik.setFieldValue(name, byteArray);
}