HTML filepicker multi - получить файлы в использовании


12

Следующая проблема возникла при использовании Firefox v73 в Windows 7:

В моем коде я использую многофайловую сборку в html для загрузки до 100 файлов:

<input type="file" id="files" name="files" multiple>

Файлы будут отправлены в REST-API, который затем обрабатывает их. Когда я выбираю один файл (в проводнике файлов), который используется в настоящее время, я получаю сообщение об ошибке (вероятно, по окну), которое говорит мне, что файл не может быть выбран, потому что он используется. Если я пытаюсь выбрать несколько файлов, которые содержат один или несколько используемых файлов, у меня не возникает никаких ошибок, но загрузка останавливается при достижении используемого файла и в ожидании выпуска файла. Это приводит к просьбе подождать таймаут (в моем случае это 1 минута).

Есть ли возможность поймать проблему (в файле использования), прежде чем пытаться загрузить файлы?

PS: я попробовал то же самое в Chrome, и он возвращает ошибку перед отправкой запроса в REST-API.


Можете ли вы показать свой вызов AJAX?
Ислам Эльшобокший

Ответы:


3

Это звучит как проблема ОС.
Что-то блокирует доступ к вашему файлу, и это требует исправления на вашей стороне.

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

Чтобы избежать большого количества операций ввода-вывода, вы можете даже попытаться прочитать только небольшую его часть, благодаря Blob.prototype.slice() методу.

const input = document.getElementById('inp');
const btn = document.getElementById('btn');

btn.onclick = async(evt) => {
  testAllFilesAvailability(input.files)
    .then(() => console.log('all good'))
    .catch(() => console.log('some are unavailable'));
}

function testAllFilesAvailability(files) {
  return Promise.all(
    [...files].map(file =>
      file.slice(0, Math.min(file.size, 4)) // don't load the whole file
      .arrayBuffer() // Blob.prototype.arrayBuffer may require a polyfill
    )
  );
}
<pre>
1. Select some files from the input
2. Change one of this files name on your hard-drive or even delete it
3. Press the button
</pre>

<input type="file" multiple id="inp">
<button id="btn">Test Availability</button>


Спасибо Кайидо за решение. Есть ваша +50 репутация. Спасатель!
Кевин Х.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.