2011-08-04 11 views
2

Main.javajava將GZIPOutputStream&ByteArrayOutputStream包裝在一起 - 我做錯了什麼?

import java.io.IOException; 

public class Main 
{ 

    private final CompressedOutputStream m_cos; 

    public static void main(String[] args) 
    { 
     try 
     { 
      final Main m = new Main(new CompressedOutputStream()); 
      m.run(); 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    public Main(final CompressedOutputStream cos) 
    { 
     this.m_cos = cos; 
    } 

    private void trace(final String format, Object... args) 
    { 
     final String output = String.format(format, args); 
     System.out.println(output); 
    } 

    public void run() 
    { 
     this.first_write(); 
     this.second_write(); 
     this.trace("CRC32 of data is %x", this.m_cos.get_crc32()); 
    } 

    private void add_data(final byte[] data) 
    { 
     try 
     { 
      this.m_cos.write(data); // STEPPING INTO THIS IN DEBUG DOESN'T LEAD ANYWHERE! 
     } 
     catch (IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    public void first_write() 
    { 
     final String[] text_lines = new String[] { "Hello world!", 
       "My name is Joe.", "Nice to meet.", "Where are you from?", 
       "I'm from Congo" }; 

     for (final String text_line : text_lines) 
     { 
      final byte[] data = text_line.getBytes(); 
      this.add_data(data); 
     } 

     final byte[] compressed_data = this.m_cos.get_compressed_data(); 
     trace("Compressed data length (so far) is %d bytes", 
       compressed_data.length); 
    } 

    public void second_write() 
    { 
     final byte[] additional_data = new byte[] { 0x00, 0x01, 0x02, 0x03, 
       0x04, 0x05, 0x06, 0x07, 0x08, 0x09 }; 
     this.add_data(additional_data); 

     final byte[] total_compressed_data = this.m_cos.get_compressed_data(); 
     trace("Total compressed data length is %d bytes", 
       total_compressed_data.length); 
    } 
} 

CompressedOutputStream.java

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.util.zip.Deflater; 
import java.util.zip.GZIPOutputStream; 

public class CompressedOutputStream extends GZIPOutputStream 
{ 

    private final ByteArrayOutputStream m_out; 

    public CompressedOutputStream() throws IOException 
    { 
     this(32); 
    } 

    public CompressedOutputStream(int size) throws IOException 
    { 
     super(new ByteArrayOutputStream(size), size); 
     this.m_out = (ByteArrayOutputStream) this.out; 
     this.def.setLevel(Deflater.BEST_COMPRESSION); 
    } 

    public long get_crc32() 
    { 
     return this.crc.getValue(); 
    } 

    public byte[] get_compressed_data() 
    { 
     return this.m_out.toByteArray(); 
    } 
} 

所以我有這樣的代碼,其試圖GZIPOutputStream與ByteArrayOutputStream合併。

出於某種原因,我得到的是相同的10個字節。
獲得這樣的輸出:

壓縮數據長度(到目前爲止)是10個字節
總壓縮數據 長度爲10個字節
數據的CRC32是4550d94d

好像調用寫( )以抽象函數結束,即它不會得到任何地方,也不會寫任何東西。
我希望它能夠被動態地寫入,壓縮,並且能夠在稍後的時間獲取壓縮字節。

缺少什麼我在這裏?看起來微不足道,但並非如此。

編輯#1:我的最終目標
只是爲了澄清:在結束所有我需要的是一個內存緩衝區,而我會寫,以塊的形式,而不是在一個序列,並在某些時候,當它會達到X字節,我將能夠採取這些,壓縮&校驗和,字節(將它們寫入某處,而不是標準的Java流)。

+0

注意:關於「在調試中步入這個問題不是任何地方」的評論,忽略它,這只是我使用JRE而不是JDK。現在它進入代碼(步入)......但主要問題仍然存在。 – Poni

+0

看看這個答案http://stackoverflow.com/q/6717165/779408 – breceivemail

回答

6

GZIPOutputStream在將數據傳遞到鏈中的下一個 流(本例中爲ByteArrayOutputStream)之前會進行一些內部緩衝。因此,您必須關閉()流才能將字節讀出。例如,我提出了以下修改second_write():

this.m_cos.close(); 
final byte[] total_compressed_data = this.m_cos.get_compressed_data(); 
trace("Total compressed data length is %d bytes", total_compressed_data.length); 

這給我的輸出:

壓縮數據長度(到目前爲止)是10個字節
總壓縮數據長度爲98字節的數據
CRC32是4550d94d

如果您不能負擔關閉流,有可能是一種方法來強制刷新內部緩衝機智關閉。 (flush()本身並不這樣做,我試過了)。

+0

這可能有所幫助:http://stackoverflow.com/questions/3640080/force-flush-on-a-gzipoutputstream-in-java – biziclop

+0

所以我必須每次分配一個NEW對象(兩個之一)?!?!?我不能相信這是所有Java必須提供的。 – Poni

+0

@biziclop在這個頁面沒有找到任何有用的東西(或者根本沒有注意到),請特別指出,如果可能的話。對不起,麻煩了,謝謝。 – Poni