Saving a Uint8Array to a binary file

21,284

Solution 1

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

Solution 2

(shorter) ES6 version of the top answer:

const downloadURL = (data, fileName) => {
  const a = document.createElement('a')
  a.href = data
  a.download = fileName
  document.body.appendChild(a)
  a.style.display = 'none'
  a.click()
  a.remove()
}

const downloadBlob = (data, fileName, mimeType) => {

  const blob = new Blob([data], {
    type: mimeType
  })

  const url = window.URL.createObjectURL(blob)

  downloadURL(url, fileName)

  setTimeout(() => window.URL.revokeObjectURL(url), 1000)
}
Share:
21,284

Related videos on Youtube

bryc
Author by

bryc

;_)

Updated on July 09, 2022

Comments

  • bryc
    bryc almost 2 years

    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?

  • Hans
    Hans over 6 years
    This confuses me, the parameters in downloadURL are different to the parameters used to call it.
  • Stefan
    Stefan over 6 years
    the example uses downloadBlob (the first function) that then calls downloadURL so the args reflect the first function not the 2nd one
  • Hans
    Hans over 6 years
    You are calling downloadURL(url, filename, mimeType) from within downloadBlob but the function is downloadURL(data, filename), so unless there is same magic happening that I don't understand, it's not matching. I think it's a case of just removing the mimeType but when first trying to understand it it's still confusing.
  • bryc
    bryc over 5 years
    FileSaver.js is a pretty solid library for handling file downloads across multiple browsers. Under the hood it does essentially the same thing as your code but adjusts for different browsers that don't support the method.