HTML filepicker multi - получить файлы в использовании - PullRequest
12 голосов
/ 19 февраля 2020

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

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

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

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

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

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

Ответы [ 2 ]

3 голосов
/ 02 марта 2020

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

Я сомневаюсь, что это будет распространенная проблема, и довольно сложно создать решение, не сталкиваясь с той же проблемой, но одну вещь, которую вы можете попробовать, это прочитать ваши файлы перед вами Отправить их. Это может быть сделано довольно удобно с помощью метода 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
    )
  );
}

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
Проверка доступности
0 голосов
/ 02 марта 2020

Для выбора нескольких файлов, почему вы не используете https://github.com/blueimp/jQuery-File-Upload

...