2012-05-11 6 views
6

Sto cercando di implementare un servlet per lo streaming di oggetti di grandi dimensioni:response.flushBuffer() non funziona

oracle.sql.BLOB blob = rs.getBLOB('obj'); 
    InputStream in = blob.getBinaryStream(); 

    int bufferSize = 1024; 
    byte[] buffer = new byte[bufferSize]; 

    ServletOutputStream out = response.getOutputStream(); 

    int counter=0 
    while((length=in.read(buffer)) != -1){ 
     out.write(buffer,0,length); 
     counter++; 
     if(counter % 10 == 0){ 
     counter=0; 
     response.flushBuffer(); 
    } 

Questo codice supponiamo di inviare dati al pezzo client chunck. Ora, ciò che accade è che quando flusso l'oggetto di grandi dimensioni (100 MB), la memoria sale e il server muore a volte se ci sono più di un download/stream parallelo.

Perché questo flushBuffer() non invia dati al client? Il client diventa popup per aprire/salvare il file solo dopo la chiusura della risposta.

+0

Inoltre ho utilizzare JOBSS 4.3 sever per testare questo codice – Madhu

+0

vieni da qualche parte 'out.close()'? – Osw

+0

sì io faccio out.close() ma non incollato qui – Madhu

risposta

3

È necessario impostare l'intestazione Content-Length prima di scrivere i dati, oppure il server è costretto a bufferizzare tutti i dati fino a quando il flusso non viene chiuso, a quel punto può calcolare il valore stesso, scrivere l'intestazione e inviare tutto il dati. Non appena si ottiene il flusso di uscita, prima di scrivere i dati a tutti, impostare la lunghezza del contenuto:

response.setHeader("Content-Length", String.valueOf(blob.length())); 

maggior parte dei server sono abbastanza intelligenti per irrigare il loro tampone a questo punto, quindi probabilmente non hanno nemmeno è necessario chiamare flushBuffer() - anche se non fa male.

+1

Mi sono stancato. Non è una cosa felice :-) – Madhu

+0

A seconda delle tue preferenze, potresti anche fare 'response.setContentLength (blob.length());' – Stuporman

1

Prima di tutto, è necessario un header di risposta per la risposta servlet modo che il contenitore può sapere dopo quanti byte può alla fine informazioni:

response.setHeader("Content-Length", String.valueOf(blob.length()));