HTML filepicker multi: obtenga archivos en uso

12

El siguiente problema ocurrió usando Firefox v73 en Windows 7:

En mi código, uso un selector de múltiples archivos en html para cargar hasta 100 archivos en paralelo:

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

Los archivos se enviarán a una REST-API que los procesará posteriormente. Cuando selecciono un solo archivo (en el explorador de archivos) que está actualmente en uso, recibo un mensaje de error (probablemente por ventana) que me dice que el archivo no se puede seleccionar porque está en uso. Si trato de elegir varios archivos que contienen uno o más archivos en uso, no tengo ningún error, pero la carga parece detenerse cuando se alcanza el archivo en uso y esperando que se libere el archivo. Esto lleva a la solicitud de esperar un tiempo de espera (que es 1 minuto en mi caso).

¿Hay alguna opción para detectar el problema (archivo en uso) antes de intentar cargar los archivos?

PD: He intentado lo mismo en Chrome y devuelve un error antes de enviar la solicitud a REST-API.

Kevin H.
fuente
¿Puedes mostrar tu llamada ajax?
Islam Elshobokshy

Respuestas:

3

Eso suena como un problema del sistema operativo.
Algo está bloqueando el acceso a su archivo y esto necesita una solución de su parte.

Dudo que sea un problema común, y es bastante difícil crear una solución sin poder experimentar el mismo problema, pero una cosa que puedes intentar es leer tus archivos antes de enviarlos. Esto se puede hacer de manera bastante conveniente con el Blob.prototype.arrayBuffermétodo, que se puede rellenar.

Para evitar muchas E / S, incluso puede intentar leer solo una pequeña parte, gracias al Blob.prototype.slice() método.

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>

Kaiido
fuente
Gracias Kaiido por la solución. Ahí tienes tu reputación de +50. ¡Salvador de la vida!
Kevin H.