Newsgroup: it.comp.java
Titolo: BufferedInputStream legge meno di quanto dovrebbe!

Sto implementando una classe che legge tramite socket una risposta (una 
pagina html) da un webserver, in realtà sto creando un proxy che fa da ponte 
tra il mio browser e internet. Per ricevere la risposta uso la classe in 
oggetto e il metodo int read(byte[] buf, int offset, int len) e continuo a 
leggere fino a quando non mi ritorna -1 (fine dei dati). Naturalmente la 
chiamata è bloccante così la lancio da un thred dedicato alla lettura 
all'avvio del programma, in modo che sia sempre pronta a riceve dati. Il 
problema è che se ad esempio l'oggetto che sto leggendo è grande 4000 byte, 
la maggior parte delle volte ne riesco a leggere sempre un numero diverso e 
comunque inferiore a quanto dovrebbe essere, praticamente termina prima la 
lettura, ma senza dare nessun errore o eccezione, semplicemente, anche se 
controllo con il metodo int available() (che restituisce il numero di byte 
che è possibile leggere), per lui l'oggetto è più piccolo di quanto è in 
realtà. La stranezza è che questo comportamento anomalo ce l'ho solo in fase 
di runtime, mentre se faccio un debug e inserisco un breakpoint 
immediantamente prima la lettura, allora adesso vede chiaramente che la 
grandezza dei dati da leggere è 4000 e prosegue correttamente. Questo 
problema si verifica in continuazione, ho anche provato ad usare altre 
classi quali InputStream e DataInputStream ma mi da lo stesso problema. Non 
riesco a capire come mai si comporta così? 

Tieni conto che available(), ha un modo di lavorare differente se lo
stream si riferisce ad un file locale o se si riferisce ad uno Stream che
passa da TCP/IP.
Se invochi il metodo su uno stream di un file locale, ti torna la
grandezza del file, ma se lo fai su uno stream che passa per TCP/IP, ti
torna la grandezza del buffer dati che sono giunti fino a quel momento.
Se ad esempio fai un loop dove per ogni ciclo, leggi un byte dello stream
e subito dopo ti leggi il valore di available, vedrai che sarà sempre
uguale a zero, perchè nel buffer TCP/IP quel byte che c'era te lo sei già
letto.
Posta la condizione di uscita e la lettura dello stream, sicuramente c'è
qualche inesattezza li.
Ciao.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 qualche inesattezza li.
Ecco un estrapolato del codice:
BufferedInputStream inWeb = new 
BufferedInputStream(webSocket.getInputStream());
OutputStream outBrowser = browserSocket.getOutputStream();
//inWeb legge dal socket del webserver
//outBrowser restituisce la pagina appena ricevuta al browser che ne ha 
fatto la richiesta
int i;
byte[] byteBuf = new byte[1024];
while(( i = inWeb.read(byteBuf, 0, 1024) != -1)
{
    outBrowser.write(byteBuf, 0, i);
    outBrowser.flush();
}
Per quanto riguarda la condizione d'uscita, inWeb.read() esce quando gli 
ritorna -1, quindi in effetti per lui i dati sarebbero finiti, perň č senza 
senso perchč la pagina č molto piů grande di quanto riesce a leggere lui. 
Poi č da sottolineare una cosa: se metto un breakpoint immediatamente prima 
la read, e poi procedo passo-passo riesco a leggere correttamente TUTTO 
l'oggetto, senza perdere niente.