Создать файл из FileReader.readAsArrayBuffer () - PullRequest
0 голосов
/ 18 июня 2020

Боюсь, я либо слишком глуп, чтобы правильно использовать Google, либо у меня странная проблема, с которой никто не знает, что они делают.

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

Я использую vue. js интерфейс с node.

Я уже могу загрузить файл как байтовый массив и загрузить этот байтовый массив обратно в интерфейс, но теперь я хочу предоставить пользователю возможность загрузить этот байтовый массив как файл .
Пользователь должен ввести тип файла на экране загрузки, и если он введет неправильный тип, файл поврежден. Это было бы нормально.
Прямо сейчас, даже когда я ввожу правильный тип файла, файл поврежден (проверено с файлами PDF и Word).

Вот мой код:
Загрузить:

<input v-if="type==types.file" id="input-field" ref="file" type="file" @change="handleFileUpload()">

      handleFileUpload(){
        this.value = this.$refs.file.files[0];
      },

      submitFile(){
        var reader = new FileReader();
        var self = this;
        reader.onload = function(event){
          self.value = new Uint8Array(event.target.result);
          self.$notify('succes', 'Dateiupload abgeschlossen');
        };
        reader.onerror = function(event){
          self.$notify('error', 'Fehler beim Dateiupload');
        }
        reader.readAsArrayBuffer(this.value);
      },

Загрузить:

parseFileValueFromByteArray(byteArray){
        const downloadElement = document.createElement('a');
        downloadElement.style.display = 'none';
        downloadElement.href = window.URL.createObjectURL(new File(byteArray, this.name));
        downloadElement.download = this.name;
        document.body.appendChild(downloadElement);
        downloadElement.click();
        window.URL.revokeObjectURL(downloadElement.href);
        return this.value;
}

Я получаю окно загрузки, чтобы открыть и загрузить файл, однако pdf-Readers (или Word, в этом случае) показывают «Файл поврежден».

Что я делаю неправильно при создании допустимого файла? Думаю, я каким-то образом кодирую метаданные файла (поскольку js файл больше, чем чистые байты) без правильного декодирования байтов.
Итак, как я могу вернуть FileReader.readAsArrayBuffer() обратно к файлу?

Заранее спасибо!

Изменить:
Странная вещь, которую я заметил: исходный размер файла pdf составляет 99 КБ. Длина byteArray составляет 100392.
Размер файла от new File(byteArray) дает размер 255 КБ. Преобразование байта в текст (с использованием new TextEncoder("utf-8).decode(byteArray))) дает мне что-то примерно похожее на открытие файла PDF с помощью блокнота ++, но открытие загруженного файла с помощью блокнота ++ дает мне поток чисел).
Может быть, это поможет найти ошибку?

1 Ответ

1 голос
/ 19 июня 2020

Итак, я исследовал больше и нашел это . Понятия не имею, почему, но вместо new Blob(byteArray) i have to do новый Blob ([byteArray]). Это дает мне возможность установить тип файла .pdf в Загрузке и получить действительный файл.

Чтобы все было в одном месте, я делаю:
Загрузить:

<input id="input-field" ref="file" type="file" @change="handleFileUpload()">
<button @click="submitFile()">Start upload</button>

handleFileUpload(){
    this.value = this.$refs.file.files[0];
},

submitFile(){
    var reader = new FileReader();
    var self = this;
    reader.onload = function(event){
        self.value = new Uint8Array(event.target.result);
        self.$notify('succes', 'File uplaoded');
    };
    reader.readAsArrayBuffer(this.value);
}

Скачать:

//this.payload is set with base64 representation of upload and then load() is called
load(){
    this.base64ToByteArray();
    this.parseFileValueFromByteArray(this.byteArrayPayload);
},

base64ToByteArray(){
    this.rawPayload = this.payload;
    this.byteArrayPayload = Uint8Array.from(atob(this.rawPayload), c => c.charCodeAt(0))
},

parseFileValueFromByteArray(byteArray){
    const downloadElement = document.createElement('a');
    downloadElement.style.display = 'none';
    downloadElement.href = window.URL.createObjectURL(new Blob([byteArray]));
    downloadElement.download = this.name;
    document.body.appendChild(downloadElement);
    downloadElement.click();
    window.URL.revokeObjectURL(downloadElement.href);
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...