2011-04-13 2 views
5

다음 코드는 javadocs for java.util.zip.Deflater에 제공된 예제를 기반으로합니다. 내가 만든 유일한 변경 사항은 dict라는 바이트 배열을 만든 다음 setDictionary (byte []) 메서드를 사용하여 Deflater 및 Inflater 인스턴스에서 사전을 설정하는 것입니다.사용자 정의 사전에 Java Deflater/Inflater를 사용하면 IllegalArgumentException이 발생합니다.

내가보기에는 내가 Deflater에 사용했던 것과 똑같은 배열로 Inflater.setDictionary()를 호출 할 때 IllegalArgumentException이 발생한다. 나는 사전을 설정하지 않고 같은 압축 된 바이트를 배출하기하려고하면

import java.util.zip.Deflater; 
import java.util.zip.Inflater; 

public class DeflateWithDictionary { 
    public static void main(String[] args) throws Exception { 
     String inputString = "blahblahblahblahblah??"; 
     byte[] input = inputString.getBytes("UTF-8"); 
     byte[] dict = "blah".getBytes("UTF-8"); 

     // Compress the bytes 
     byte[] output = new byte[100]; 
     Deflater compresser = new Deflater(); 
     compresser.setInput(input); 
     compresser.setDictionary(dict); 
     compresser.finish(); 
     int compressedDataLength = compresser.deflate(output); 

     // Decompress the bytes 
     Inflater decompresser = new Inflater(); 
     decompresser.setInput(output, 0, compressedDataLength); 
     decompresser.setDictionary(dict); //IllegalArgumentExeption thrown here 
     byte[] result = new byte[100]; 
     int resultLength = decompresser.inflate(result); 
     decompresser.end(); 

     // Decode the bytes into a String 
     String outputString = new String(result, 0, resultLength, "UTF-8"); 
     System.out.println("Decompressed String: " + outputString); 
    } 
} 

, 내가 오류를 얻을 있지만, 반환되는 결과가 0 바이트 : 여기

문제의 코드입니다.

Deflater/Inflater에서 사용자 지정 사전을 사용하려면 특별히 필요한 것이 있습니까?

답변

7

질문을 공식화하는 동안 실제로 이것을 알아 냈지만 어쨌든 질문을 게시하여 다른 사람들이 저의 고투에서 이익을 얻을 수 있다고 생각했습니다.

입력을 설정 한 후에 inflate()를 한 번 호출해야하지만 전에 사전을 설정해야합니다. 돌려 주어지는 값은 0으로, needsDictionary()의 호출은 true를 돌려줍니다. 그 후에 사전을 설정하고 다시 부 풀릴 수 있습니다. 다음과 같이

수정 된 코드는 다음과 같습니다

import java.util.zip.Deflater; 
import java.util.zip.Inflater; 

public class DeflateWithDictionary { 
    public static void main(String[] args) throws Exception { 
     String inputString = "blahblahblahblahblah??"; 
     byte[] input = inputString.getBytes("UTF-8"); 
     byte[] dict = "blah".getBytes("UTF-8"); 

     // Compress the bytes 
     byte[] output = new byte[100]; 
     Deflater compresser = new Deflater(); 
     compresser.setInput(input); 
     compresser.setDictionary(dict); 
     compresser.finish(); 
     int compressedDataLength = compresser.deflate(output); 

     // Decompress the bytes 
     Inflater decompresser = new Inflater(); 
     decompresser.setInput(output, 0, compressedDataLength); 
     byte[] result = new byte[100]; 
     decompresser.inflate(result); 
     decompresser.setDictionary(dict); 
     int resultLength = decompresser.inflate(result); 
     decompresser.end(); 

     // Decode the bytes into a String 
     String outputString = new String(result, 0, resultLength, "UTF-8"); 
     System.out.println("Decompressed String: " + outputString); 
    } 
} 

이 더 좋은 대안이 있다면 그렇게 가르치 려하시기 바랍니다 매우 카운터 직관적이고 어설픈 API를 디자인의 관점에서 보인다.

+4

'needsDictionary()'의 이유는 zlib 형식이 동일한 응용 프로그램에서 다른 사전을 사용할 수있게하고 파일 헤더에 사전의 Adler32 체크섬을 표시한다는 것입니다. 이 헤더를 읽으려면 압축 된 쪽의 응용 프로그램에 올바른 사전을 선택하게하려면 'inflate'의 첫 번째 호출이 필요합니다. –

+0

내가 이것을했을 때, 나는 inquisitively sense하는 inflate() 전에 사전을 설정할 필요가 있었다. 그래서 무언가가 당신의 모범에서 ... – Chris

관련 문제