Сохранение Uint8Array в двоичный файл

Я работаю над веб-приложением, которое открывает двоичные файлы и позволяет их редактировать.

Этот процесс в основном ondrop -> dataTransfer.files[0] -> FileReader -> Uint8Array

По сути, я хочу иметь возможность сохранить измененный файл в виде двоичного файла. В идеале как загрузка файла с указанным именем файла.

Кажется, не существует какого-либо стандартного метода сделать это, и это отстой, потому что все, что было до этого момента, хорошо поддерживается.

В настоящее время я преобразовываю массив в строку, используя String.fromCharCode(), кодировку base64 и используя uri данных в гиперссылке, такой как data:application/octet-stream;base64,.., вместе с атрибутом download для указания имени файла.

Кажется, это работает, но довольно хакерски, и я думаю, что преобразование необработанных байтов в строку может привести к проблемам с кодировкой в ​​зависимости от значений байтов. Я не хочу, чтобы данные были повреждены или сломали строку.

За исключением этого, есть ли лучший/правильный метод для получения массива байтов в виде двоичного файла для пользователя?


person bryc    schedule 17.08.2014    source источник


Ответы (2)


Это утилиты, которые я использую для кроссбраузерной загрузки файлов. Изящная вещь в этом заключается в том, что вы можете установить свойство download ссылки на имя, которое вы хотите, чтобы ваше имя файла было.

К вашему сведению, mimeType для двоичного файла равен 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();
};

Использование:

downloadBlob(myBinaryBlob, 'some-file.bin', 'application/octet-stream');
person Stefan    schedule 10.11.2015
comment
Это меня смущает, параметры в URL-адресе загрузки отличаются от параметров, используемых для его вызова. - person Hans; 27.01.2018
comment
в примере используется downloadBlob (первая функция), которая затем вызывает downloadURL, поэтому аргументы отражают первую функцию, а не вторую - person Stefan; 27.01.2018
comment
Вы вызываете downloadURL(url, filename, mimeType) из downloadBlob, но функция downloadURL(data, filename), поэтому, если не происходит той же магии, которую я не понимаю, она не соответствует. Я думаю, что это случай простого удаления mimeType, но при первой попытке понять это все еще сбивает с толку. - person Hans; 28.01.2018
comment
FileSaver.js — довольно надежная библиотека для обработки загрузки файлов в нескольких браузерах. Под капотом он делает то же самое, что и ваш код, но настраивается для разных браузеров, которые не поддерживают этот метод. - person bryc; 27.08.2018

(короче) версия ES6 верхнего ответа:

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)
}
person v1rtl    schedule 03.06.2020