Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 866
bryc Avatar asked Aug 17 '14 22:08

bryc


People also ask

How to write data to binary file?

fwrite( fileID , A ) writes the elements of array A as 8-bit unsigned integers to a binary file in column order. The binary file is indicated by the file identifier, fileID . Use fopen to open the file and obtain the fileID value. When you finish writing, close the file by calling fclose(fileID) .

What is a binary file and how is it used?

A binary file is a type of computer file that is used to store binary data. It may contain any type of formatted or unformatted data encoded within binary format. It is used directly by the computer and generally can't be read by a human. Binary files may also be called binaries.


2 Answers

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');
like image 81
Stefan Avatar answered Oct 19 '22 03:10

Stefan


(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)
}
like image 13
v1rtl Avatar answered Oct 19 '22 02:10

v1rtl