Saving a Uint8Array to a binary file
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)
}
Related videos on Youtube
Comments
-
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 likedata:application/octet-stream;base64,..
, along with thedownload
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 over 6 yearsThis confuses me, the parameters in downloadURL are different to the parameters used to call it.
-
Stefan over 6 yearsthe example uses
downloadBlob
(the first function) that then callsdownloadURL
so the args reflect the first function not the 2nd one -
Hans over 6 yearsYou are calling
downloadURL(url, filename, mimeType)
from withindownloadBlob
but the function isdownloadURL(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 themimeType
but when first trying to understand it it's still confusing. -
bryc over 5 yearsFileSaver.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.