2013-10-10 8 views
10

Sto sviluppando un'applicazione FileShare con webRTC. Voglio implementare il client in JavaScript/HTML. Il codice dovrebbe essere eseguito sul browser dei client. Ho bisogno di salvarli quando scaricati tramite webRTC. I file possono essere abbastanza grandi e non posso scaricarli completamente e salvarli in una matrice o blob prima di salvarli su disco come file.Salva i dati generati dal client come file in JavaScript in blocchi

Esiste un API che mi permette di salvare il file in blocchi come li ricevo?

Ho trovato finora Downloadify, FileSave.js e html5 FileWriterApi finora. Mentre i primi due non sono suddivisi in blocchi e mi impongono di scaricare prima il file completo in memoria prima di salvarlo, FileWriterAPI non è disponibile sulla maggior parte dei browser.

+0

http://help.infragistics.com/Help/NetAdvantage/ASPNET/2013.1/CLR4.0/html/WebUpload_Saving_Files_as_Stream.html http://www.aurigma.com/docs/iu7/saving-uploaded- file-in-aspnet.htm ho questo due link che possono aiutare –

+0

per i file di dimensioni ragionevoli, il mio primo istinto è quello di memorizzare ogni pezzo nel proprio 'Blob', unisciti a loro tutti insieme in un unico grande' Blob' alla fine (usando il nuovo costruttore) e usate 'createObjectURL' per salvare l'ultimo' Blob'.IIRC, JS 'Blob's sono archiviati su disco dove necessario, quindi a meno che i file non siano veramente enormi (o io sono veramente sbagliato;)), non dovrebbe essere troppo orribile? –

+0

@JordanGray Potrebbe essere una buona idea - ho ipotizzato che i blocchi scaricati debbano essere mantenuti per il download continuo tra le sessioni del browser, ma in caso contrario, questa potrebbe essere l'idea più pulita (se i browser implementano il persistere del blob su file quando necessario). –

risposta

11

Come @ Jordan-grigio suggerito, salvare i pezzi nel blob e unendoli ad un blob più grande potrebbe essere una soluzione se:

  • Persistenza di blocchi non è necessario (ad esempio la chiusura del browser eliminerà tutti i blocchi)
  • Il file viene mantenuto solo dall'utente che lo salva sul proprio file system. L'applicazione web non avrà accesso al file una volta chiuso, a meno che l'utente non abbia dato nuovamente accesso al file salvato.
  • Probabilmente, se le dimensioni del file non sono troppo grandi (dovrete fare un benchmark per scoprirlo). Chrome si stava comportando abbastanza bene per me per pezzi che ammontavano a 1GB.

Ho creato un simple test for using blobs as chunks. Si può giocare con i diversi parametri di dimensione e Chunk numeri:

var chunkSize = 500000; 
var totalChunks = 200; 
var currentChunk = 0; 
var mime = 'application/octet-binary'; 
var waitBetweenChunks = 50; 

var finalBlob = null; 
var chunkBlobs =[]; 

function addChunk() { 
    var typedArray = new Int8Array(chunkSize); 
    chunkBlobs[currentChunk] = new Blob([typedArray], {type: mime}); 
    console.log('added chunk', currentChunk); 
    currentChunk++; 
    if (currentChunk == totalChunks) { 
     console.log('all chunks completed'); 
     finalBlob = new Blob(chunkBlobs, {type: mime}); 
     document.getElementById('completedFileLink').href = URL.createObjectURL(finalBlob); 
    } else { 
     window.setTimeout(addChunk, waitBetweenChunks); 
    } 
} 
addChunk(); 

Se avete bisogno che la persistenza, il W3C File System API dovrebbe sostenere quello che ti serve. Puoi usarlo per scrivere i blocchi per separare i file, e quando tutti i blocchi sono completati puoi leggerli tutti e aggiungerli a un singolo file e rimuovere i blocchi.

Nota che funziona tramite l'assegnazione di un file system in modalità sandbox per l'applicazione (per un determinato contingente), ei file sono accessibili solo a quell'applicazione. Se i file devono essere utilizzati al di fuori dell'applicazione Web, potrebbe essere necessario utilizzare la funzione per salvare il file dal filesystem dell'applicazione al suo filesystem "normale". Puoi fare qualcosa del genere usando il metodo createObjectURL().

Hai ragione sullo stato attuale del supporto del browser. A Filesystem API polyfill è disponibile, che è basato su IndexedDB (che è più ampiamente supportato) come un back-end di emulazione del filesystem. Non ho testato il polyfill su file di grandi dimensioni. Potresti incorrere in limiti di dimensioni o limitazioni delle prestazioni.

+0

Sì, questo è più o meno quello che avevo in mente. Sulla base della mia comprensione delle specifiche, dovrebbe essere in grado di scalare ragionevolmente bene, con blocchi persistenti alla memoria sottostante, laddove necessario. :) –

+0

Sembra che questo sia ancora stato salvato in memoria prima '(currentChunk == totalChunks)' prima di salvare su disco, corretto? – dman

+0

No, pensa al nuovo Blob() come se restituisse un puntatore a un oggetto sul disco. https://developer.mozilla.org/en/docs/Web/API/Blob –

3

Hai controllato https://github.com/Peer5/Sharefest fuori? Esso dovrebbe coprire le esigenze

+2

sembra essere un problema anche per loro ... https://github.com/Peer5/ShareFest/issues/53 –