javascriptfile-iocross-browserbinary-datatyped-arrays

Saving a Uint8Array to a binary file


I am working on a web app that opens binary files and allows them to be edited.

This process is basically ondrop -> dataTransfer.files[0] -> FileReader -> Uint8Array

Essentially, I want to be able to save the modified file back as a binary file. Ideally as a file download with a specified file name.

There doesn't seem to be any standard method of doing this, and that sucks, because everything up to that point is well supported.

I am currently converting the array to a string using String.fromCharCode(), base64 encoding that, and using a data uri in a hyperlink like data:application/octet-stream;base64,.., along with the download attribute to specify filename.

It seems to work, but it's quite hacky and I think converting the raw bytes to a string might introduce encoding issues depending on the byte values. I don't want the data to become corrupt or break the string.

Barring that, is there a better/proper method for getting an array of bytes as a binary file to the user?


Solution

  • These are utilities that I use to download files cross-browser. The nifty thing about this is that you can actually set the download property of a link to the name you want your filename to be.

    FYI the mimeType for binary is application/octet-stream

    var downloadBlob, downloadURL;
    
    downloadBlob = function(data, fileName, mimeType) {
      var blob, url;
      blob = new Blob([data], {
        type: mimeType
      });
      url = window.URL.createObjectURL(blob);
      downloadURL(url, fileName);
      setTimeout(function() {
        return window.URL.revokeObjectURL(url);
      }, 1000);
    };
    
    downloadURL = function(data, fileName) {
      var a;
      a = document.createElement('a');
      a.href = data;
      a.download = fileName;
      document.body.appendChild(a);
      a.style = 'display: none';
      a.click();
      a.remove();
    };
    

    Usage:

    downloadBlob(myBinaryBlob, 'some-file.bin', 'application/octet-stream');