2013-10-10 4 views
3

문자열 압축 및 압축 해제를위한 다음 코드가 있습니다.GZIP는 개행 문자를 사용합니다.

public static byte[] compress(String str) 
{ 
    try 
    { 
     ByteArrayOutputStream obj = new ByteArrayOutputStream(); 
     GZIPOutputStream gzip = new GZIPOutputStream(obj); 
     gzip.write(str.getBytes("UTF-8")); 
     gzip.close(); 
     return obj.toByteArray(); 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
    return null; 
} 

public static String decompress(byte[] bytes) 
{ 
    try 
    { 
     GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); 
     BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8")); 
     StringBuilder outStr = new StringBuilder(); 
     String line; 
     while ((line = bf.readLine()) != null) 
     { 
      outStr.append(line); 
     } 
     return outStr.toString(); 
    } 
    catch (IOException e) 
    { 
     return e.getMessage(); 
    } 
} 

Windows에서 바이트 배열로 압축 한 다음 소켓을 통해 바이트 배열을 보내서 거기에서 압축을 풉니 다. 그러나 압축을 풀면 모든 개행 문자가 사라진 것처럼 보입니다.
그래서 나는 문제가 리눅스 관계에 윈도우 관계라고 생각. 그러나 그것을 사용하는 Windows에서 간단한 프로그램을 작성하려고 시도하고 개행이 사라 졌음을 발견했습니다.
아무도 그 원인을 밝힐 수 있습니까? 나는 어떤 설명도 이해할 수 없다.

답변

4

나는 문제가 여기에 생각하십시오 readLine

while ((line = bf.readLine()) != null) 
    { 
     outStr.append(line); 
    } 

는 개행 문자입니다 그러나 아마 line

문제는 당신이 생각하는 것보다 더 나쁜에 대한 반환 값에 포함되지 않습니다.

readLine()은 줄 바꿈 (또는 다양한 반환 및 줄 바꿈 문자) 또는 파일 끝을 포함하여 모든 문자를 가져옵니다. 그래서 마지막 줄에 마지막 줄 바꿈이 있는지 알지 못합니다.

이 중요하지 않을 수 있습니다, 만약 그렇다면, 당신은 단지 다른 APPEND 다음이를 추가 할 수 있습니다

outStr.append('\n'); 

일부 파일은 파일의 끝에서 끝나는 여분의 줄을 끝낼 수 있습니다.

중요한 경우 read()을 사용하고 수신 한 모든 문자를 출력해야합니다. 이 경우 악명 높은 "결국에는 무엇이 있을까요?"라고 끝낼 수도 있습니다. Windows, Linux 및 MacOS 사이에서 언급 한 문제와 최종 줄에 반환 및 줄 바꿈 문자의 다양한 조합을 사용하는 방법에 대해 설명합니다.

+0

당신이 옳았습니다. 'read()'는 방금 실패했지만, 내 경우에는'.append ("\ n")'이 작동하고 추가 줄 바꿈을 얻었지만 지금까지는 발생하지 않았다면 괜찮습니다. – Quillion

5

개식을 "먹는"GZIP가 아닙니다.

while ((line = bf.readLine()) != null) 
    { 
     outStr.append(line); 
    } 

readLine() 방법 (라인 종결 서열에 포함까지) 라인을 읽은 다음 줄 바꿈없이 그것을 를 반환

그것은이 코드입니다. 그런 다음 outStr ... 에 추가하고은 제거 된 회선 종단 코드를 대체하지 않습니다.

하지만 줄 종결을 바꾸더라도 실제로 사용 된 줄 끝 시퀀스를 그대로 유지한다고 보장 할 수는 없습니다.

호출을 read() 호출로 바꾸는 것이 좋습니다. 즉 한 번에 한 문자 씩 판독하고 버퍼링한다. 한 번에 두 가지 문제를 해결합니다. 줄 문자열을 어셈블하는 불필요한 오버 헤드를 피하기 때문에 더 빠를 수도 있습니다.

+0

나는 매우 유감 스럽다. 그러나 Lee가 처음이었다.또한 read()를 사용하여 불행하게도 다른 문자를 사용하여 다른 OS로 인해 시도했다. 소켓을 통해 데이터를 하나에서 다른 것으로 전송할 때 개행 문자가 사용되지 않는다. 도움을 주셔서 감사합니다 :) 솔루션은 옳았고 정말 좋아했습니다. – Quillion