Unexpected end of stream

17 respostas
L

Pessoal, alguém pode me ajudar.

Estou fazendo o download de um arquivo para o meu app (android) de um servidor web (Tomcat) e no meio do download dá o erro abaixo:

java.io.IOException: unexpected end of stream at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:48) at java.io.InputStream.read(InputStream.java:163) at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142) at java.io.BufferedInputStream.read(BufferedInputStream.java:309) at java.io.InputStream.read(InputStream.java:163)

17 Respostas

L

Ninguem???

Estou a dias com esse problema.

G

codigo

L

Gilson, esse é o código que faz o download. O problema ocorre no While.

Cara já faz uma semana que estou com esse problema, estou até pensando em mudar a forma de download e puder me ajudar ficarei muito grato.
Pq se tivesse q mudar a forma de download, vou ter q alterar muito estrutura do programa

private String downloadArquivo(String sUrl, Comunica vo) {
		String MainUrl = sUrl+"/Arquivos/Liberado/"+vo.getUsuario()+"/"+vo.getUsuario()+".zip";
	    InputStream input = null;
		OutputStream output = null;
		try {
			URL url = new URL(MainUrl);
			connection = (HttpURLConnection) url.openConnection();
			connection.setInstanceFollowRedirects(false);
			//			connection.setReadTimeout(setReadTimeout); 
			//			connection.setConnectTimeout(setConnectTimeout); 
			connection.setDoInput(true);  
			connection.setDoOutput(true);  
			connection.setUseCaches(false);  
			connection.setChunkedStreamingMode(0);
			connection.setRequestMethod("POST");
			connection.setRequestProperty("Connection", "Keep-Alive");
			connection.setRequestProperty("http.keepAlive", "false");
			connection.setRequestProperty ( "User-Agent" , "" );
			connection.setRequestProperty("Keep-Alive", "header");
			connection.setRequestProperty("Content-Type","multipart/zip'; charset = UTF-8");
			connection.setRequestProperty ("Accept-Encoding", "");
			if  (Build.VERSION.SDK !=  null  &&  Build.VERSION.SDK_INT >  13)  { 
				connection.setRequestProperty("Connection", "close"); 
			}
			controlSessionClienteServer();

			if (connection.getResponseCode() == 200){
				String fileName = "";
				String disposition = connection.getHeaderField("Content-Disposition");
				if (disposition != null) {
					int index = disposition.indexOf("filename=");
					if (index > 0) {
						fileName = disposition.substring(index + 10, disposition.length() - 1);
					}
				} else {
					fileName = MainUrl.substring(MainUrl.lastIndexOf("/") + 1, MainUrl.length());
				}

				input = new BufferedInputStream(connection.getInputStream());
				output = new FileOutputStream(Constantes.DIR_RECEB + File.separator + fileName);

				byte buffer[] = new byte[1024];
				long downloadedSize = 0;
				int bufferLength;

				int totalSize = connection.getContentLength();
				ci.pbSetMaxProgressBar(totalSize); //Barra de Progresso
				while ((bufferLength = input.read(buffer)) != -1) {
					downloadedSize += bufferLength;
					output.write(buffer, 0, bufferLength);
					publishProgress("","",String.valueOf(downloadedSize),String.valueOf(totalSize+"/"+downloadedSize).toString()+" bytes - Download");
				}
				return "0";	
			}else{
				return "1";
			}
		} catch (Throwable e) {
			ExceptionAFV.setMsgErro(e, cxt, false);	
			_MSGCOM = e.getMessage().toString();
			return "1";
		} finally {
			try {
				if (output != null)
					output.close();
				if (input != null)
					input.close();
			} catch (IOException ioe) {}
			if (connection != null)
				connection.disconnect();
		}
	}

Obrigado.

G

tente assim:

pode ter algum erro de sintaxe, visto q não tenho como testar aki, não uso java.

int totalSize = connection.getContentLength();  
            ci.pbSetMaxProgressBar(totalSize); //Barra de Progresso 
            int restante = totalSize;
            while (restante > 0){
               bufferLength = restante;
               if (bufferLength > buffer.length) //no maximo 1024
                 bufferLength = buffer.length;  
                 
               bufferLength = input.read(buffer, 0, bufferLength);
               if (bufferLength == -1) 
                 break;   
                
               downloadedSize += bufferLength;  
               output.write(buffer, 0, bufferLength);  
               restante -= bufferLength; //p saber qto falta
               
               publishProgress("","",String.valueOf(downloadedSize),String.valueOf(totalSize+"/"+downloadedSize).toString()+" bytes - Download");  
            }
L

Gilson, continua dando o mesmo erro:

O erro acontece na linha abaixo no codigo que me passou:

Não sei o que fazer, pelo jeito vou ter q alterar toda a estrutura de donwload do programa.

Uma coisa que eu não disse é:
Esse erro só acontece depois que estou o pacote de dados contratado 30mb onde a velocidade de navegação será reduzida e não bloqueada, ou seja, fica mais lento a transmissão de da esse erro.

Pela sua experiencia, será que consigo fazer um try/catch para pegar esse erro e reconectar connection.getInputStream() para continuar o donwload de onde deu o problema?

Valeu.

G

mude essa linha

input = new BufferedInputStream(connection.getInputStream());
para
input = connection.getInputStream();
G

se não funcionar, vou tentar instalar o eclipse aki pra eu testar.

L

Gilson, estava assim antes e já dava este erro.

Mas mesmo assim, fiz a alteração e o erro continua.

Acho que deve ter muito timeout por a conexão 3g reduzir a velocidade apos estourar o pacote de dados, é inacreditável que é só estourar o pacote de dados q da esse problema.

Tenho que achar uma solução para reconectar e continuar o download de onde deu esse problema, acho que assim vou ter uma solução.

Valeu.

G

ele lança a exceção pq os dados ainda não estão disponíveis. mas é so ver como configura pra ele retonar q não conseguiu ler, é assim q sockets funcionam.

L

Gilson, desculpe não entendi. Você pode me dar uma ajuda para resolver esse problema?

At.

L

Gilson, só completando a msg anterior

Iniciar o download e esse erro acontece no meio do download quando fica oscilando o rede de dados da operadora.

Acho que vai ser difícil achar uma solução, se pelo menos eu pudesse tratar um try/catch para iniciar o download de onde acontecesse este erro.

At.

L

Olha eu de novo, e que não sei mais o que fazer com esse problema. Quem puder me ajude,

Gilson, estou aqui fazendo outros testes para fazer o download e agora estou utilizando as classes: ReadableByteChannel e FileChannel.

O arquivo que estou fazendo download tem 1324309 bytes e sempre quando o quando o downlodas chega 131071 bytes encerra a conexão e dá o erro o mesmo erro:

Segue o erro e o código que faz o download.

java.io.IOException: unexpected end of stream
	at libcore.net.http.FixedLengthInputStream.read(FixedLengthInputStream.java:48)
	at java.io.InputStream.read(InputStream.java:163)
	at java.nio.channels.Channels$InputStreamChannel.read(Channels.java:306)
	at java.nio.FileChannelImpl.transferFrom(FileChannelImpl.java:387)
private String downloadArquivo(String sUrl, Comunica vo) {
		String MainUrl = sUrl+"/Arquivos/Liberado/"+vo.getUsuario()+"/"+vo.getUsuario()+".zip";
		ReadableByteChannel in = null;
		FileChannel out = null;
		try {
			File output = new File (Constantes.DIR_RECEB + File.separator + vo.getUsuario()+".zip");
			URL url = new URL(MainUrl);
			connection = (HttpURLConnection) url.openConnection();
			if (connection.getResponseCode() == 200){
				long length = connection.getContentLength();
				ci.pbSetMaxProgressBar(length);
				in = Channels.newChannel(connection.getInputStream());
				out = new FileOutputStream(output).getChannel();
				long pos = 0;
				while (pos < length){
					Log.v("Script", String.valueOf(length - pos));
					pos += out.transferFrom(in, pos, length - pos);
					publishProgress("","",String.valueOf(pos).toString(),String.valueOf(length+"/"+pos).toString()+" bytes - Download");
				}

				return "0";	
			}else{
				return "1";
			}
		} catch (Exception e) {
			ExceptionAFV.setMsgErro(e, cxt, false);	
			_MSGCOM = e.getMessage().toString();
			return "1";
		} finally { 
			try {
				if (in != null){
					in.close();	
				}
				if (out != null){
					out.close();	
				}
			} catch (IOException e) {
				ExceptionAFV.setMsgErro(e, cxt, false);	
				_MSGCOM = e.getMessage().toString();
			} 
		}
	}

Valeu.

G

eu testei o codigo aki e funcionou normalmente. ma não em mobile

L

Esse problema do FileChannel que publiquei, o engracado que se o arquivo for menor que 131071 bytes faz o donwload certinho no 3G e no Wifi.

Agora se for maior somente faz o donwload no wifi no 3G da esse erro.

Vai saber e vai entender!!!

Como resolver isso?

KKKK

L

Outro detalhe:

O erro “Unexpected end of stream” só ocorre quando o pacote de dados é estourado, por exemplo:

A operadora que utilizamos é a Vivo e o pacote de dados contratado é de 30mb, quando estoura o pacote de dados contratado a operadora reduz a velocidade e aí já não consigo fazer download dos arquivos maiores 100kb.

Caso não estoura o pacote de dados tudo funciona direitinho.

Tá complicado!

At.

G

o q ocorre é q qdo não tem dado disponível, o inputstream lança uma exceção.
ele poderia retornar q não leu (return = 0)

provavelmente tem algum maneira de saber se tem dado disponivel.

pq ele ta tratando como stream de arquivo, por exemplo, nesse caso qdo não tem dado disponível, é pq chegou ao fim, mas um socket já não é assim, só indica q o dado ainda não chegou.

L

Valeu Gilson!

Mais não consegui encontrar uma solução, vou repensar o processo e verificar uma forma para fazer download do dados no android.

Que coisa!

Mais de 15 dias em cima e nada.

Criado 6 de agosto de 2015
Ultima resposta 21 de ago. de 2015
Respostas 17
Participantes 2