2013-11-14 3 views
2

큰 base64로 인코딩 된 데이터가 있습니다 (hadoop 파일 시스템의 멋진 파일에 저장 됨). 이 데이터는 원래 gzipped 텍스트 데이터였습니다. 이 인코딩 된 데이터의 청크를 읽고 디코드 한 다음 GZIPOutputStream으로 플러시 할 수 있어야합니다.Base64 데이터의 스트림 디코딩

전체 base64 데이터를 배열에로드하고 Base64.decodeBase64 (byte [])를 호출하는 대신 어떻게 할 수 있습니까?

'\ r \ n'구분 기호까지 문자를 읽고 줄 단위로 디코딩하면 맞습니까? 예 : :

for (int i = 0; i < byteData.length; i++) { 
    if (byteData[i] == CARRIAGE_RETURN || byteData[i] == NEWLINE) { 
     if (i < byteData.length - 1 && byteData[i + 1] == NEWLINE) 
      i += 2; 
     else 
      i += 1; 

     byteBuffer.put(Base64.decodeBase64(record)); 

     byteCounter = 0; 
     record = new byte[8192]; 
    } else { 
     record[byteCounter++] = byteData[i]; 
    } 
} 

슬프게도,이 방법은 모든 사람이 읽을 수있는 출력을 제공하지 않습니다. 이상적으로는 데이터를 읽고, 디코딩하고, 스트리밍하고 싶습니다. 지금

, 나는 gzipout

byteBuffer.get(bufferBytes); 

InputStream inputStream = new ByteArrayInputStream(bufferBytes); 
inputStream = new GZIPInputStream(inputStream); 
IOUtils.copy(inputStream , gzipOutputStream); 

에의 InputStream에 넣고 복사하려고 해요 그리고 그것은 나에게 때 java.io.IOException 제공 :

+0

은'byteBuffer.put (Base64.decodeBase64 (기록)) ' 가 될 안'byteBuffer.put (Base64.encodeBase64 (레코드)) ' –

+0

는'기록 '는 Base64로 인코딩된다. 디코딩 된 데이터를 가져와 ByteBuffer에 추가하려고합니다. –

답변

3

이 가자 부패 GZIP 트레일러 단계별 :

  1. 넌 압축 데이터를 판독 할 필요 GZIPInputStream (그와 GZIPOutputStream하지 상기 출력 데이터 스트림을 압축하기 위해 사용된다). 이 스트림을 사용하면 압축되지 않은 원본 바이너리 데이터를 읽을 수 있습니다. 이 경우 생성자에 InputStream이 필요합니다.

  2. Base64로 인코딩 된 데이터를 읽을 수있는 입력 스트림이 필요합니다. 나는 편리한 Base64InputStreamapache-commons-codec에서 제안한다. 생성자를 사용하여 줄 길이, 줄 구분 기호를 설정하고 doEncode=false을 설정하여 데이터를 디코딩 할 수 있습니다. 이렇게하려면 원시, Base64로 인코딩 된 데이터 인 다른 입력 스트림이 필요합니다.

  3. 이 스트림은 데이터를받는 방법에 따라 다릅니다. 이상적으로 데이터는 InputStream - 문제가 해결 된 것으로 사용할 수 있어야합니다. 그렇지 않다면, 당신은 등 ByteArrayInputStream (진 경우), StringBufferInputStream (만약 문자열)

를 사용 할 수 있습니다 대충이 논리는 다음과 같습니다

InputStream fromHadoop = ...;         // 3rd paragraph 
Base64InputStream b64is =          // 2nd paragraph 
    new Base64InputStream(fromHadoop, false, 80, "\n".getBytes("UTF-8")); 
GZIPInputStream zis = new GZIPInputStream(b64is);    // 1st paragraph 

(Base64InputStream의 인수에주의하십시오 행 길이 및 행 끝 바이트 배열)을 수정해야 할 수도 있습니다.

+0

고마워, Nikos. Base64InputStream 클래스가 도움이되었습니다. –

0

정확한 방향으로 나를 가리키는 Nikos에게 감사드립니다.

private static final byte NEWLINE = (byte) '\n'; 
private static final byte CARRIAGE_RETURN = (byte) '\r'; 

byte[] lineSeparators = new byte[] {CARRIAGE_RETURN, NEWLINE};  
Base64InputStream b64is = new Base64InputStream(inputStream, false, 76, lineSeparators); 

GZIPInputStream zis = new GZIPInputStream(b64is); 

(76)가 Base64로 라인의 길이 아닌가 : 는 특히이 내가 무슨 짓을? 나는 80으로 시도하지 않았다.

+0

길이가 76으로 고정되면 생성자 인수가 포함되지 않습니다. 또한 모든 것이 한 줄인 데이터 URI에 대해 생각해보십시오. – TWiStErRob