2013-03-05 3 views
2

GZIPInputStream을 사용하여 PDF 파일을 다운로드하고 있습니다. 파일의 다운로드 진행 상황을 UI 단추에 표시하고 싶습니다. 하지만, 파일의 실제 크기를 얻지 못하고 있는데, 압축 크기 때문에 올바른 다운로드 진행 상태를 표시 할 수 없습니다. 실제 파일 크기가 압축 된 파일 크기보다 커서이 다운로드 진행률은 100을 초과합니다.압축 된 파일의 크기를 서버에서 가져올 수있는 비 압축 gzip 파일의 크기를 확인하십시오.

서버에서 보낸 파일의 헤더 내용 : 다음 정보 내가 압축 된 파일 크기를 제공하는 content-length을 사용중인 서버로부터 수신했습니다.

1.Connection 
2.Content-Encoding 
3.Content-length 
4.Content-Type 
5.Keep-Alive 
6.Server 
7.Date 

여기 내 코드입니다. 파일의 원래 크기를 얻는 방법이 있습니까?

long fileLength = httpResponse.getEntity().getContentLength();// 
GZIPInputStream input = new GZIPInputStream(new BufferedInputStream(
     httpResponse.getEntity().getContent())); 
FileOutputStream output = new FileOutputStream(destinationFilePath); 

byte data[] = new byte[1024]; 
long total = 0; 
float percentage = 0; 
int count; 
currentDownloadingPercentage=0; 
while ((count = input.read(data)) != -1) { 
    total += count; 
    output.write(data, 0, count); 

    // publishing the progress.... 
    percentage = (float)total/(float)fileLength; 
    percentage *= 100; 
    if ((int)percentage > (int)currentDownloadingPercentage) { 
     currentDownloadingPercentage = percentage; 
     Bundle resultData = new Bundle(); 
     resultData.putBoolean(DOWNLOAD_FAILED, false); 
     resultData.putInt(DOWNLOAD_PROGRESS ,(int)percentage); 
     receiver.send(processID, resultData); 
     resultData = null; 
    } 
} 

답변

0

잘못된 방식으로보고 있습니다. 읽은 압축 바이트 수를 계산하고이를 기반으로 진행 상황을 계산해야합니다. 대신 압축 해제 된 바이트 수를 계산하여 압축 된 파일 크기와 비교합니다. 귀하의 질문에 대한 답변으로 압축 해제하지 않고 gzip 파일의 크기를 결정할 수있는 (신뢰할 수있는) 방법이 없습니다.

업데이트 : 여기 하나의 방법은 오는 압축되지 않은 바이트 카운트 GZIPInputStream로 포장하기 전에 TeeInputStream와 원시 입력 스트림을 감싸고 있었다.. TeeInputStream 분기를 CountingOutputStream으로 만듭니다. 당신이 gzip 압축을 수용 할 수 HttpURLConnection의 일단 그럼 당신은 항상 HttpURLConnection.getInputStream()을 피하기 위해 방법을 getByteCount()

+0

진행률 부분에서 잘 작동하는 InputStream을 사용하여 시도했지만 스트림이 압축 파일을 생성했습니다. 이 파일의 압축을 풀 때 오프라인 모드에서 평소보다 많은 시간이 걸렸습니다. 파일을 위해 바이트 단위로 압축을 풀기 위해 완전히 다른 라운드가 진행되었습니다. 다음은 압축 된 바이트 만 읽는 코드입니다.InputStream input = 새로운 BufferedInputStream (httpResponse.getEntity(). getContent()); –

+0

압축 된 바이트를 계산하는 방법으로 답변을 업데이트했습니다. –

+0

Ryan, 안드로이드에서 어떻게해야합니까? android의 TeeInputStream에 대한 대안? –

0

issue 결과를 논의를 통해 다운로드 한 압축 된 바이트의 현재 카운트를하지 보인다해야 자동으로 당신은, GZIPInputStream을 반환 정확하게 우리가 허용 인코딩으로 바로 비활성화 GZIP을 할 수있는 단 하나의 다운로드 진행 상황을 계산하지 않습니다

HttpURLConnection.setRequestProperty("Accept-Encoding", "identity"); 

는 또 다른 선택은 AndroidHttpClient을 사용됩니다, 난 우리가 이런 GZIP 인코딩을 받아 제시, 이것에 대해 시험했다 :

HttpUriRequest.addHeader("Accept-Encoding", "gzip"); 

원래의 InputStream는 우리가 원하는 것입니다 EofSensorInputStream이 될 것입니다 HttpResponse.getEntity().의 getContent()에 의해 반환되는 InputStream 인스턴스에 의해 GZIPInputStream 그것을 포장하는 우리가 가능하게 GZIPInputStream 아니다 우리는 TeeInputStream과 CountingOutputStream을 사용하여 다운로드 진행 상황을 계산할 수 있습니다.

HttpResponse response = ...; 
HttpEntity entity = response.getEntity(); 
long fileSize = entity.getContentLength(); 

InputStream ins = entity.getContent(); // instance of EofSensorInputStream 
CountingOutputStream coStrem = new CountingOutputStream(new ByteArrayOutputStream(100)); 
GZIPInputStream inStrem = new GZIPInputStream(new TeeInputStream(ins, coStrem, true)); 

byte[] buffer = new byte[6 * 1024]; // 6K buffer 
int offset; 

while ((offset = inStrem.read(buffer)) != -1) { 
    tmpFileRaf.write(buffer, 0, offset); 
    postDownloadProgress(fileSize, coStrem.getByteCount()); 
} 

나는 그것이 우리가이 문제로 할 수있는 모든 생각, 그래서 우리는 사용자 정의 할 수 있습니다 내 프로젝트 android libcore 소스를 데리러 시도 다음은 GZIPInputStream을 반환 억제하지만, 많은 오류가 문제를 만들고, 나는이 노력을 폐기 HttpURLConnectionImpl .

post에서 Jesse Wilson은 Android의 최선의 선택 클라이언트 인 HttpURLConnection을 제안 했으므로이 문제를 항상 해결하는 방법을 찾고 있습니다. 곧 나올 수 있기를 바랍니다.

관련 문제