2015-01-23 5 views
0

나는 InputStream를하고 난 그것을 처리하기 위해 노력하지만, "gzip이 아니라 형식으로"나에게이 오류 듯했으나 파일은 gzip 형식으로 "콘텐츠 인코딩 : gzip을"JAVA되지는

protected String readResponse(InputStream is) throws IOException { 
StringBuffer string; 
int b; 
byte[] buffer; 
String eol, s = null; 
GZIPInputStream gis; 
int read; 
int index; 


eol = new String(new byte[] {(byte)0, (byte)0, (byte)-1, (byte)-1}); 
buffer = new byte[1]; 
string = new StringBuffer(); 
while ((b = is.read()) > 0) { 
    buffer[0] = (byte)b; 
    s = new String(buffer); 
    string.append(s); 
    index = string.indexOf(eol); 
    if (index > 0 && index == string.length() - 4) { 
    break; 
    } 

} 

System.out.println(string); 

gis = new GZIPInputStream(is); << here I got the error 
buffer = new byte[1024]; 

while ((read = gis.read(buffer)) > 0) { 
    string.append(new String(buffer, 0, read)); 
} 
return string.toString(); 

}

의견이 있으십니까? 감사합니다.

+2

그렇다면 자바가 거짓말하고 있다고 말하는 것입니까? – Kayaman

+2

그 코드로 달성하고자하는 것이 무엇인지 모르겠지만 여기에 힌트가 있습니다 : _ 이진 데이터에'String'을 사용하지 마십시오 _ – fge

+0

파일이나 처음 100 바이트 정도를 hexdump로 게시 할 수 있습니까? – Adam

답변

1

이 광고보기 전에 :

EOL을 = 새로운 문자열 (새 바이트 [{(바이트) 0 (바이트) 0 (바이트) -1- (바이트) -1});

은 결론에 도달하기에 충분합니다. 처음부터 운명의 여지가 있습니다.

이진 데이터에는 문자열을 사용하지 마십시오.

bytes 및 char에는 서로 관계가 없습니다. 당신이 여기서하고있는 것은 다음과 거의 동일합니다 :

final CharsetDecoder decoder = Charset.defaultCharset() 
    .newDecoder().onMalformedInput(CodingErrorAction.REPLACE); 
final ByteBuffer buf = ByteBuffer.wrap(new byte[]{...}); 
final CharBuffer cbuf = decoder.decode(buf); 
final String eol = new String(cbuf.array()); 

참고 REPLACE 작업입니다. 매핑 할 수없는 바이트 시퀀스는 디코더가 유니 코드 대체 문자 U+FFFD을 출력하도록 트리거합니다 (익숙한 모양입니까?).

대신 REPORT을 입력하십시오.

무엇보다 기본 charset을 사용합니다 ... 플랫폼마다 다릅니다.

코드는 실제로 입력 스트림을 읽고 byte 배열을 반환해야합니다. ByteArrayOutputStream을 사용하십시오.

파일에 직접 쓰려면 간단합니다. Files.copy()을 사용하십시오.

어쨌든, 고정 당신을 위해 :

// Note: return code is byte[] 
protected byte[] readResponse(final InputStream in) 
    throws IOException 
{ 
    try (
     final InputStream gzin = new GzipInputSream(in); 
     final ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    ) { 
     final byte[] buf = new byte[4096]; 
     int bytesRead; 
     while ((bytesRead = gzin.read(buf)) != -1) 
      out.write(buf, 0, bytesRead); 

     return out.toByteArray(); 
    } 
} 
+0

코드가 작동하지만 서버가 변경되어 더 이상 작동하지 않았습니다! 그것은 작동했다 !!! –

+0

그것은 순수한 _luck_에 의해 작동했다. 행운을 믿지 마라. "수시로"작동하지 않는 코드가 작동하지 않습니다. – fge

+0

여전히 여기에 같은 오류가 발생합니다. 마지막 InputStream gzin = new GZIPInputStream (is); –

0

GZIPInputStream에 전달하기 전에 입력 스트림에서 파일 포인터를 앞으로 올리는 것이 문제 일 수 있습니다. GZIPInputStream는 처음 몇 바이트가 표준 헤더가 될 것으로 예상합니다.

새로운 GZIPInputStream (is)을 이동해보십시오. 사용자의 while 루프

+0

Adam, 고맙습니다. 이전에 나 한테 똑같은 오류를주었습니다. –

0

이 코드에서 잘못된 너무 많은 일이 ..... 어쨌든 시도 할 수 있습니다. 그래서 ascii 헤더가 있고 거기에 shoulbe gzipped 부분이 있습니까? Gzip 파일은 항상 id 바이트로 시작합니다. 고정 값 'ID1 = 31 (0x1f, \ 037), ID2 = 139 (0x8b, \ 213)'입니다. 당신은 당신의 입력 스트림에서 그것들을 찾을 수 있습니까? 거기에서 gzipstream을 시작해야합니다.

+0

도움을 주셔서 감사합니다.이 사진을 확인하십시오. http://i.imgur.com/6FGodJE.png gzip 파일을 검색하려면 어떻게해야합니까? –

+0

@ikettu 일단 마법을 보았다면, gzip으로 된 스트림을 어디에서 읽을 지 이미지나 갔다. 이것을 어떻게 요리 할 것을 제안합니까? 그리고 왜 HTTP 헤더의 끝을 모니터링하는 것이 더 간단하지 않습니까? – laune

+0

푸시 백 스트림을 사용하여 미리 들여다 볼 수 있습니다. 하지만 테스트하는 동안 바이트 코드를 검사하면 머리글의 끝을 표시하는 실제 바이트를 알 수 있습니다. – ikettu

0

몇 줄의 헤더 행과 빈 줄, 추가 된 gzipped 텍스트 파일로 구성된 파일로 테스트했습니다. 후자는 확장되지 않은 채로 x.gz로 작성되고 압축이 풀리고 거기에서 읽습니다. 텍스트 파일이라고 가정합니다. (이진 파일 인 경우 BufferedReader는 무의미합니다.)

리소스를 시도하고 추가해야하지만 이는 단지 기술적 인 부분입니다.

InputStream is = ...; 
StringBuilder lsb = new StringBuilder(); 
int c = -1; 
while((c = is.read()) != -1){ 
    if(c == '\n'){ 
     String line = lsb.toString(); 
     if(line.matches("\\s*")){ 
      break; 
     } 
     System.out.println(line); 
     lsb.delete(0, lsb.length()); 
    } else { 
     lsb.append((char)c); 
    } 
} 
byte[] buffer = new byte[1024]; 
int nRead = 0; 
OutputStream os = new FileOutputStream("x.gz"); 
while ((nRead = is.read(buffer, 0, buffer.length)) > 0) { 
    os.write(buffer, 0, nRead); 
} 
os.close(); 
is.close(); 

InputStream gis = new GZIPInputStream(new FileInputStream("x.gz")); 
InputStreamReader isr = new InputStreamReader(gis); 
BufferedReader br = new BufferedReader(isr); 
String line; 
while((line = br.readLine()) != null){ 
    System.out.println("line: " + line); 
} 
br.close(); 
+0

내 컴퓨터에서 gzip 파일을 찾아 gunzip하려고했지만 "gzip 형식이 아닙니다"라고 말하면 서버에서 gzip 파일이라고 말했지만 그렇지 않습니다! –

+0

게시 한 코드를 사용한 경우 어떻게 실패했는지 알 수 없습니다.- 어쨌든, 헤더를 끝내는 빈 줄 뒤에 보낸 것이 무엇이든 정확한 복사본을 가지고 있습니다. 아마도이 바이트의 분석을 통해 실제로 무엇인지를 알 수 있습니다. 물론 실제 사이트에 액세스 할 수 없습니다 ... 의심스러운 파일을 드롭 할 수 있는지 여부는 확실하지 않습니다. - gzip을 사용하여 헤더로 시작하는 파일에 대한 부록을 만들었고, 코드 스 니펫이 잘 실행됩니다. - 최소한 : 헤더 파일은 빈 줄과 함께 끝내야합니다. 그 줄 뒤에 횡설수설을 나타내지 않습니다. 그렇습니까? – laune