Upload velkých souborů pomocí JSP
Nevěděl by někdo jak efektivně řešit upload např. 5GB velkýho souboru? Měl jsem na plánu něco jako buffer konstantní velikosti a když se naplní tak data zapsat na disk a znovu načitat data do bufferu. A tak pořád dokola dokud budou přicházet data. Měl by někdo lepší řešení?
Re: Upload velkých souborů pomocí JSP
Tak jak to píšeš, tak se to většinou dělá :)
Re: Upload velkých souborů pomocí JSP
Dík, takhle mě to zatim funguje pro soubory do cca 500MB. U vetších se nic nestane. Nenastavuje se někde v TomCatu max velikost soboru?
Re: Upload velkých souborů pomocí JSP
Mno ja bych pro takle velky soubory udelal neco sofistikovanejsiho, treba java aplet a webovou sluzbu prijimaci rozsekany soubor po mensich paketech...
Re: Upload velkých souborů pomocí JSP
Citace:
Původně odeslal
MEluZíNa
Mno ja bych pro takle velky soubory udelal neco sofistikovanejsiho, treba java aplet a webovou sluzbu prijimaci rozsekany soubor po mensich paketech...
Asi máš pravdu, protože přes http nepujde poslat velký soubor, jelikož conntent-length v http headeru je typu int, takže pro vetší soubory přeteče. Přes ten applet myslíš na serveru vytvořit aplikaci, která bude přijmat datovej stream z apletu?
Re: Upload velkých souborů pomocí JSP
Ještě jsem narazil na problém. Když posílám data na server pomocí metody write třídy DataOutputStream (v cyklu je plnen buffer a pak je odesilan)
Kód:
vystup.write(buffer,0,nactenoCelkem);
a na serveru je přijmám metodou read třídy DataInputStream (v cyklu je plnen buffer a pak je zapsan)
Kód:
nacteno = vstup.read(buffer,nactenoCelkem,velikostBufferu-nactenoCelkem);
tak nevim jak na serveru zjistit zda byli odeslany všechny data. Klient dokončí odesílání dat a server stále čeká na data. Když u klienta zavřu výstupní stream, tak server čekat přestane. Dalo by se to řešit jinak, aniž bych musel zavírat outputStream?
Re: Upload velkých souborů pomocí JSP
Podle me ne (resp ano, poslat specialni sekvenci bajtu, podle niz to poznas). V cem je problem, ze ti vadi Stream zavrit?
Re: Upload velkých souborů pomocí JSP
Protože bych pak ještě potřeboval přijmout potvrzení od serveru, že byl soubor úspěšně nahrán. Když Output stream zavřu, tak se mi zavře i Input stream. Myslel jsem že jsou na sobě nezávislý... Po zavření se mi ho nepodaří znova otevřít, resp. nevim jak...
Kdybych tam poslal sekvenci bajtu, tak bych na serveru musel každý přijatý buffer kontrolovat zda neni posledni... I kdyz to by nebylo tak hrozny. dejme tomu, že by byl buffer delky 100B a na prvních 99 by byli data a na poslednim bajtu by byl identifikátor zda jsou tyto data posledni.
Re: Upload velkých souborů pomocí JSP
Moh bys jeste jednou priblizit jak to delas? Posles normalne HTTP POST request jehoz obsahem je ten soubor? Nejlip kdyz posles kus zdrojaku, takle moc nevim jak to mas.
Re: Upload velkých souborů pomocí JSP
Ne, přes http to neni. Na serveru běží démon co přijmá spojení od klientu a vytváří vlákna pro příjem dat od klientů.
Spojení navazuji pomoci tříd Socket a ServerSocket.
Vysvětlivky:
vstup - DataInputStream
vystup -DataOutputStream
cteni - FileInputStream
zapis - FileOutputStream
klient:
Kód:
byte buffer[] = new byte[velikostBufferu];
int nacteno=0;
long nactenoCelkem=0;
while (nacteno!=-1){
nacteno = cteni.read(buffer,nactenoCelkem,velikostBufferu-nactenoCelkem); //cteni ze souboru
if (nacteno!=-1){
nactenoCelkem+=nacteno;
}
if ((nactenoCelkem+10000>=velikostBufferu) || (nacteno == -1)){
vystup.write(buffer,0,nactenoCelkem);
if (nacteno!=-1){
nacteno = 0;
}else{
vystup.close();
}
nactenoCelkem = 0;
}
}
server
Kód:
while (nacteno!=-1){
nacteno = vstup.read(buffer,nactenoCelkem,velikostBufferu-nactenoCelkem); //cteni dat ze socketu
if (nacteno!=-1){ // pokud byli nacteny data
nactenoCelkem += nacteno;
}
if ((nactenoCelkem+10000>=velikostBufferu) || (nacteno == -1)){ //jestlize je buffer plny(je tam rezerva aby nepretekl) nebo nebyli nacteny data
zapis.write(buffer,0,nactenoCelkem); //zapis do souboru
if (nacteno!=-1){
nacteno = 0;
}
nactenoCelkem = 0;
}
}
takhle to funguje kdyz se zavre ten OutputStream u klienta. Tim vrati metoda read na serveru -1
Re: Upload velkých souborů pomocí JSP
Tak jsem na to přišel. Ten OutputStream se musi zavirat na socketu metodou
Kód:
socket.shutdownOutput();
a ne na DataOutputStreamu který jsem získal a zavíral takto
Kód:
vystup = new DataOutputStream(socket.getOutputStream());
vystup.close();
Teď jestli mam ten vystup na konci zavirat taky. Asi jo. Žádnou vyjímku to nehází...
Docela by mě zajímalo jestli lze ten output na socketu znovu otevřít...