HTML filepicker multi - ottenere i file in uso


12

Il seguente problema si è verificato utilizzando Firefox v73 su Windows 7:

Nel mio codice uso un multi-file-picker in html per caricare fino a 100 file in parallelo:

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

I file verranno inviati a un'API REST che li elaborerà in seguito. Quando seleziono un singolo file (nel file explorer) che è attualmente in uso, ricevo un messaggio di errore (probabilmente dalla finestra) che mi dice che il file non può essere prelevato perché è in uso. Se provo a scegliere più file che contengono uno o più file in uso, non si verifica alcun errore, ma il caricamento sembra arrestarsi quando viene raggiunto il file in uso e in attesa del rilascio del file. Questo porta a richiedere di attendere un timeout (che nel mio caso è di 1 minuto).

Esiste un'opzione per rilevare il problema (file in uso) prima di provare a caricare i file?

PS: ho provato lo stesso in Chrome e restituisce un errore prima di inviare la richiesta all'API REST.


Puoi mostrare la tua chiamata Ajax?
Islam Elshobokshy,

Risposte:


3

Sembra un problema con il sistema operativo.
Qualcosa sta bloccando l'accesso al tuo file e questo ha bisogno di una correzione dalla tua parte.

Dubito che sarà un problema comune ed è abbastanza difficile creare una soluzione senza essere in grado di provare lo stesso problema, ma una cosa che puoi provare è leggere i tuoi file prima di inviarli. Questo può essere fatto abbastanza convenientemente con il Blob.prototype.arrayBuffermetodo, che può essere polifillato.

Per evitare molti I / O, puoi anche provare a leggere solo una piccola parte di esso, grazie al Blob.prototype.slice() metodo.

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>


Grazie Kaiido per la soluzione. Ci sono la tua reputazione +50. Salvavita!
Kevin H.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.