2013-10-10 29 views
10

Zajmuję się tworzeniem aplikacji FileShare z webRTC. Chcę zaimplementować klienta w JavaScript/HTML. Kod powinien być uruchamiany w przeglądarce klienta. Muszę je zapisać po pobraniu przez webRTC. Pliki mogą być dość duże i nie mogę ich całkowicie załadować i zapisać w tablicy lub blobie przed zapisaniem ich na dysku jako pliku.Zapisz dane wygenerowane przez klienta jako plik w języku JavaScript w porcjach

Czy istnieje interfejs API, który umożliwia zapisanie pliku w porcjach, gdy je otrzymuję?

Znalazłem do tej pory Downloadify, FileSave.js i html5 FileWriterApi do tej pory. Podczas gdy pierwsze dwa nie są porcjowane i wymagają wcześniejszego pobrania całego pliku do pamięci przed zapisaniem, FileWriterAPI nie jest dostępny w większości przeglądarek.

+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- files-in-aspnet.htm Mam dwa linki, które mogą ci pomóc –

+0

Dla plików o rozsądnej wielkości, moim pierwszym instynktem jest przechowywanie każdego fragmentu w jego własnym 'Blob', łączenie ich wszystkich razem w jeden duży' Blob' na końcu (używając nowego konstruktora) i użyj 'createObjectURL', aby zapisać ostateczny' Blob'.IIRC, JS 'Blob's są przechowywane na dysku w razie potrzeby, więc chyba że pliki są naprawdę ogromne (lub jestem naprawdę źle;)), to nie powinno być zbyt przerażające? –

+0

@JordanGray Może być dobrym pomysłem - założyłem, że pobrane fragmenty muszą być utrwalone do ciągłego pobierania między sesjami przeglądarki, ale jeśli nie, może to być najczystszy pomysł (jeśli przeglądarki implementują utrzymywanie blob do pliku, gdy jest to potrzebne). –

Odpowiedz

11

Jako @ Jordan-szary zasugerował, zapisywania fragmentów w bąble i łączenie ich do większej blob może być rozwiązaniem, jeśli:

  • Trwałość kawałki nie jest potrzebne (tj zamknięcie przeglądarki spowoduje usunięcie wszystkich porcji)
  • Plik jest zachowywany tylko przez użytkownika, który zapisał go w swoim własnym systemie plików. Aplikacja internetowa nie będzie miała dostępu do pliku po jego zamknięciu, chyba że użytkownik ponownie uzyska dostęp do zapisanego pliku.
  • Ewentualnie, jeśli rozmiary plików nie są zbyt duże (aby to stwierdzić, musisz przeprowadzić analizę porównawczą). Chrome zachowywał się dla mnie całkiem nieźle, jeśli chodzi o kawałki o łącznej pojemności 1 GB.

Stworzyłem simple test for using blobs as chunks. Możesz poeksperymentować z różnymi parametrami wielkości i chunk liczbach:

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(); 

Jeśli tak trzeba, że ​​wytrwałość, W3C File System API powinien wspierać to, co trzeba. Możesz go użyć do zapisania porcji w oddzielnych plikach, a gdy wszystkie porcje zostaną ukończone, możesz je wszystkie przeczytać i dołączyć do pojedynczego pliku, a następnie usunąć porcje.

Należy pamiętać, że działa to poprzez przypisanie piaskownicy systemu plików dla danej aplikacji (dla danego przydziału), a pliki są dostępne tylko dla tej aplikacji. Jeśli pliki mają być używane poza aplikacją WWW, może być potrzebna funkcja do użycia, aby zapisać plik z systemu plików aplikacji do "normalnego" systemu plików. Możesz zrobić coś takiego, używając metody createObjectURL().

Masz rację co do aktualnego stanu obsługi przeglądarki. Dostępny jest model A Filesystem API polyfill oparty na standardzie IndexedDB (który jest obsługiwany częściej) jako zaplecza emulacji systemu plików. Nie testowałem polyfill na dużych plikach. Możesz napotkać ograniczenia rozmiaru lub ograniczenia wydajności.

+0

Tak, to jest to, co miałem na myśli. W oparciu o moją wiedzę na temat specyfikacji, powinien on być w stanie skalować się w rozsądny sposób, przy czym w razie potrzeby fragmenty muszą być przechowywane w pamięci masowej. :) –

+0

Wygląda na to, że to jest nadal zapisywane do pamięci najpierw '(currentChunk == totalChunks)' przed zapisaniem na dysku, czyż nie? – dman

+0

Nie, pomyśl o nowym obiekcie Blob(), tak jakby zwracał wskaźnik do obiektu na dysku. https://developer.mozilla.org/en/docs/Web/API/Blob –