2013-07-13 2 views
5

Deflater.setLevel()이 예상대로 작동하지 않습니다.Deflater.setLevel()이 작동합니까?

static void test1() throws Exception { 
    byte[] output = new byte[20]; 
    Deflater compresser = new Deflater(); 
    // compresser.setLevel(Deflater.BEST_COMPRESSION); 
    compresser.setInput("blah".getBytes("UTF-8")); 
    compresser.finish(); 
    int len = compresser.deflate(output); 
    System.out.println("len="+ len+ " " +Arrays.toString(output)); 
} 

나를 위해 확인 위의 작품 (자바 7) ,하지만 난 compresser.setLevel() 행의 주석을 해제 할 때, 그것은 나누기 (deflate() 반환 0 바이트). DEFAULT을 제외한 모든 압축 수준에서도 마찬가지입니다. 좀 더 구체적으로, 레벨 세트가 생성자에서 (명시 적으로 또는 암시 적으로, 여기에서와 같이) 설정된 것과 동일 할 때만 (즉, 무해한) "작동"합니다. 즉 쓸모없는 경우에만 사용될 수 있습니다.

예 : Ideone을 참조하십시오.

This question이 같은 문제를 지적하고 있습니다. 대답은 기본적으로 다음과 같습니다. 설정자와 레벨을 설정하지 말고 생성자에서 수행하십시오. 만족스럽지 못한 IMO - setLevel()은 왜 존재합니까? 부러 지거나 뭔가 빠졌습니까?

+0

'Deflater' API에 버그가있는 것 같습니다. javadoc을 읽으면'.finish()'가 실제로하는 일이 명확하지 않습니다. 마지막 답변에서 제안 된 해결 방법이 효과가 있습니까? – fge

답변

5

나는 JDK 소스 코드를 조금 파헤 쳤다. 실제로 레벨을 설정합니다. setLevel()compresser.deflate(new byte[0]);으로 따라 가면 작동합니다.

setLevel() 이후에 처음으로 deflate()을 호출하면 레벨이 변경된 것으로 나타나고 zlib의 deflateParams() 함수를 호출하여 변경해야합니다. deflateParams()은 사용 가능한 데이터를 압축하지만 finish()을 요청한 사실은 전달되지 않습니다. JDK 구현에서는 deflate()Z_FINISH으로 호출하지 않습니다. 결과적으로 사용자가 지정한 데이터는 압축을 위해 전송되고 압축기는 데이터를 누적 시키지만 완료를 요청받지 않았으므로 압축 된 블록을 방출하지 않습니다. 그래서 당신은 아무것도 얻지 못합니다.

실제로 레벨을 설정하려면 setLevel() 뒤에 deflate()으로 전화해야합니다. 이후 데이터는 새로운 레벨로 압축됩니다.

setLevel() 후 제 deflate() 호까지 제공된 데이터 이전 압축률로 압축되어야한다는 것을 명심해야한다. 전화 번호 deflate() 이후에 제공된 데이터 만 새 레벨을 사용합니다. 따라서 예제에서 단순히 deflate()을 마지막으로 수행 한 경우 finish()이 적용되고 압축 된 데이터가 표시되지만 기본 압축 수준을 사용합니다.

+0

"당신이 finish()를 요청했다는 사실은"그게 버그일까요? " – leonbloy

+0

나는 그렇다고 대답 할 것이다. 특히 그 행동이 문서화 된 곳을 보지 못했기 때문에 특히 그렇습니다. –

3

이것이 버그 인 것 같습니다.

당신이 source code으로 보면, 당신은 단지 생성자가 네이티브 메소드 실제로 압축의 레벨을 설정 init 전화 않는다는 것을 발견 할 것이다. 네이티브 init 호출이 발생하기 전에 압축 수준을 설정해야합니다. Deflater 개체를 만들기 전에 압축 수준을 설정해야합니다.

setLevel(int)은 피사체의 레벨을 표면적으로 설정합니다. 네이티브 라이브러리에 대한 호출이 없습니다.

+0

'setLevel()'이 변장의 NOP (... [1998] (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4152809)에 고정되어 있음) 그러나 그것은 더 나빠요, 그것은 감압을 깨는 것 같습니다. – leonbloy

+0

다음에'deflate()'를 호출하면 레벨이 설정됩니다. –