13

I try to convert a file that i get through an input file into a byte[]. I tried with a FileReader, but i must miss something :

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

But in the end, my bytes var doesn't content a byte array.

I saw this post : Getting byte array through input type = file but it doesn't ends with a byte[], and readAsBinaryString() is deprecated

What do i miss?

Community
  • 1
  • 1
Lempkin
  • 1,458
  • 2
  • 26
  • 49

5 Answers5

21

Faced a similar problem and its true the 'reader.result' doesn't end up as 'byte[]'. So I have cast it to Uint8Array object. This too is not a perfect 'byte[]' ,so I had to create a 'byte[]' from it. Here is my solution to this problem and it worked well for me.

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' is what you are looking for. Saw the comments and seems you did the same, still wanted to share the approach.

Santosh Ch
  • 211
  • 2
  • 5
5

Seems to me you just want to get files into an array? How about these functions - one where you can read it as text, another as a base64 byte string, and if you really want the readAsArrayBuffer array buffer output, I've included that, too:

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>
vapcguy
  • 7,097
  • 1
  • 56
  • 52
3

this works very well for me in 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);
}
Samira
  • 2,361
  • 1
  • 12
  • 21
2

Here is a modified, and in my opinion easier version of the accepted answer. This function returns a Promise with a value of the byte[].

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

This way you can simply call this function in an async function like this

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);
}
0
  async function getAsByteArray(file) {
    return new Uint8Array(await readFile(file));
  }

  function readFile(file) {
    return new Promise((resolve, reject) => {
      let reader = new FileReader();
      reader.addEventListener("loadend", (e) => resolve(e.target.result));
      reader.addEventListener("error", reject);
      reader.readAsArrayBuffer(file);
    });
  }
  const handleFileChange = async (file) => {
    const byteFile = await getAsByteArray(file);
  };
ak000ay
  • 18
  • 4